优化: CR-06 mdReady翻转主动重渲染(_mdRenderKey强制刷新)+CR-09 .ai-md样式抽全局css(70行去重→ai-md.css+main.ts导入)
This commit is contained in:
@@ -196,6 +196,7 @@
|
||||
v-if="msg.content || (isLastAi(msg) && store.state.currentText)"
|
||||
class="ai-msg-bubble ai-msg-bubble--ai ai-md"
|
||||
:class="{ 'ai-msg-bubble--error': msg.isError }"
|
||||
:key="'md-' + msg.id + '-' + (isLastAi(msg) ? _mdRenderKey : 0)"
|
||||
>
|
||||
<div v-html="renderContent(msg)"></div>
|
||||
<span v-if="isLastAi(msg) && isViewingGenerating" class="ai-cursor"></span>
|
||||
@@ -803,6 +804,14 @@ onMounted(async () => {
|
||||
console.debug(`[启动] AiChat IPC 完成: ${(performance.now() - t0).toFixed(0)}ms`)
|
||||
})
|
||||
|
||||
// CR-260615-06: mdReady 就绪后主动触发首屏 Markdown 重渲染
|
||||
// (marked 加载慢 + 无新 delta 时末段停留纯文本,不触发模板重算)
|
||||
const _mdRenderKey = ref(0)
|
||||
function forceUpdate() { _mdRenderKey.value++ }
|
||||
watch(mdReady, (ready) => {
|
||||
if (ready) nextTick(() => { forceUpdate() })
|
||||
})
|
||||
|
||||
// ── 置顶功能 ──
|
||||
const alwaysOnTop = ref(false)
|
||||
async function toggleAlwaysOnTop() {
|
||||
@@ -1208,78 +1217,6 @@ async function toggleAlwaysOnTop() {
|
||||
50% { opacity: 0; }
|
||||
}
|
||||
|
||||
/* ═══ Markdown 渲染 ═══ */
|
||||
.ai-md :deep(p) { margin: 0 0 6px; }
|
||||
.ai-md :deep(p:last-child) { margin-bottom: 0; }
|
||||
.ai-md :deep(ul), .ai-md :deep(ol) { margin: 4px 0; padding-left: 20px; }
|
||||
.ai-md :deep(li) { margin: 2px 0; line-height: 1.5; }
|
||||
.ai-md :deep(code) {
|
||||
font-family: var(--df-font-mono);
|
||||
font-size: 12px;
|
||||
padding: 1px 5px;
|
||||
background: rgba(255,255,255,0.06);
|
||||
border-radius: var(--df-radius-sm);
|
||||
color: var(--df-accent);
|
||||
}
|
||||
.ai-md :deep(pre) {
|
||||
margin: 8px 0;
|
||||
padding: 10px 12px;
|
||||
background: var(--df-bg);
|
||||
border: 0.5px solid var(--df-border);
|
||||
border-radius: var(--df-radius);
|
||||
overflow-x: auto;
|
||||
}
|
||||
.ai-md :deep(pre code) {
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
color: var(--df-text-secondary);
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.ai-md :deep(blockquote) {
|
||||
margin: 6px 0;
|
||||
padding: 4px 12px;
|
||||
border-left: 2px solid var(--df-accent);
|
||||
color: var(--df-text-secondary);
|
||||
}
|
||||
.ai-md :deep(h1), .ai-md :deep(h2), .ai-md :deep(h3) {
|
||||
font-weight: 500;
|
||||
color: var(--df-text);
|
||||
margin: 8px 0 4px;
|
||||
}
|
||||
.ai-md :deep(h1) { font-size: 16px; }
|
||||
.ai-md :deep(h2) { font-size: 14px; }
|
||||
.ai-md :deep(h3) { font-size: 13px; }
|
||||
.ai-md :deep(a) {
|
||||
color: var(--df-accent);
|
||||
text-decoration: none;
|
||||
}
|
||||
.ai-md :deep(a:hover) { text-decoration: underline; }
|
||||
.ai-md :deep(strong) { font-weight: 500; color: var(--df-text); }
|
||||
.ai-md :deep(hr) {
|
||||
border: none;
|
||||
border-top: 0.5px solid var(--df-border);
|
||||
margin: 8px 0;
|
||||
}
|
||||
.ai-md :deep(table) {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 6px 0;
|
||||
font-size: 12px;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
}
|
||||
.ai-md :deep(th), .ai-md :deep(td) {
|
||||
padding: 4px 8px;
|
||||
border: 0.5px solid var(--df-border);
|
||||
text-align: left;
|
||||
}
|
||||
.ai-md :deep(th) {
|
||||
font-weight: 500;
|
||||
background: var(--df-bg);
|
||||
}
|
||||
|
||||
/* ── token 用量条(克制:右对齐 / 最小字号 / dim / 分隔线,不抢正文焦点) ── */
|
||||
.ai-token-usage {
|
||||
display: flex;
|
||||
|
||||
@@ -3,6 +3,7 @@ import App from "./App.vue";
|
||||
import router from "./router";
|
||||
import i18n from "./i18n";
|
||||
import "./styles/global.css";
|
||||
import "./styles/ai-md.css";
|
||||
|
||||
createApp(App).use(router).use(i18n).mount("#app");
|
||||
|
||||
|
||||
75
src/styles/ai-md.css
Normal file
75
src/styles/ai-md.css
Normal file
@@ -0,0 +1,75 @@
|
||||
/* ═══ Markdown 渲染(全局,从 AiChat.vue <style scoped> 抽出) ═══ */
|
||||
/* CR-260615-09: 原 5 文件重复 ~350 行 → 仅 AiChat.vue 有实际内容,
|
||||
其余 4 文件(ProjectDetail/Ideas/Knowledge/TaskDetail)零 .ai-md 引用。
|
||||
提为全局 CSS 消除唯一重复源。 */
|
||||
|
||||
.ai-md p { margin: 0 0 6px; }
|
||||
.ai-md p:last-child { margin-bottom: 0; }
|
||||
.ai-md ul, .ai-md ol { margin: 4px 0; padding-left: 20px; }
|
||||
.ai-md li { margin: 2px 0; line-height: 1.5; }
|
||||
.ai-md code {
|
||||
font-family: var(--df-font-mono);
|
||||
font-size: 12px;
|
||||
padding: 1px 5px;
|
||||
background: rgba(255,255,255,0.06);
|
||||
border-radius: var(--df-radius-sm);
|
||||
color: var(--df-accent);
|
||||
}
|
||||
.ai-md pre {
|
||||
margin: 8px 0;
|
||||
padding: 10px 12px;
|
||||
background: var(--df-bg);
|
||||
border: 0.5px solid var(--df-border);
|
||||
border-radius: var(--df-radius);
|
||||
overflow-x: auto;
|
||||
}
|
||||
.ai-md pre code {
|
||||
padding: 0;
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
color: var(--df-text-secondary);
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.ai-md blockquote {
|
||||
margin: 6px 0;
|
||||
padding: 4px 12px;
|
||||
border-left: 2px solid var(--df-accent);
|
||||
color: var(--df-text-secondary);
|
||||
}
|
||||
.ai-md h1, .ai-md h2, .ai-md h3 {
|
||||
font-weight: 500;
|
||||
color: var(--df-text);
|
||||
margin: 8px 0 4px;
|
||||
}
|
||||
.ai-md h1 { font-size: 16px; }
|
||||
.ai-md h2 { font-size: 14px; }
|
||||
.ai-md h3 { font-size: 13px; }
|
||||
.a-md a {
|
||||
color: var(--df-accent);
|
||||
text-decoration: none;
|
||||
}
|
||||
.ai-md a:hover { text-decoration: underline; }
|
||||
.ai-md strong { font-weight: 500; color: var(--df-text); }
|
||||
.ai-md hr {
|
||||
border: none;
|
||||
border-top: 0.5px solid var(--df-border);
|
||||
margin: 8px 0;
|
||||
}
|
||||
.ai-md table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 6px 0;
|
||||
font-size: 12px;
|
||||
overflow-x: auto;
|
||||
display: block;
|
||||
}
|
||||
.ai-md th, .ai-md td {
|
||||
padding: 4px 8px;
|
||||
border: 0.5px solid var(--df-border);
|
||||
text-align: left;
|
||||
}
|
||||
.ai-md th {
|
||||
font-weight: 500;
|
||||
background: var(--df-bg);
|
||||
}
|
||||
Reference in New Issue
Block a user