main: 增加全局暗黑模式支持及 Markdown 渲染功能

- 实现暗黑模式切换逻辑,支持系统主题适配
- 优化全局样式,添加动态主题变量及暗黑样式
- 引入 `markdown-it` 和 `mermaid`,支持 Markdown 内容及流程图渲染
- 更新 ChatView 测试用例,验证 Markdown 和 Mermaid 渲染效果
- 修改 package.json,增加新依赖
This commit is contained in:
2025-12-22 12:37:59 +08:00
parent 9b48ff3e3b
commit 9280fbe762
13 changed files with 1846 additions and 165 deletions

View File

@@ -12,6 +12,12 @@ vi.mock('axios', () => ({
post: vi.fn(),
},
}))
vi.mock('mermaid', () => ({
default: {
initialize: vi.fn(),
run: vi.fn().mockResolvedValue(),
},
}))
const mockedAxios = axios
let latestEventSource = null
@@ -451,6 +457,67 @@ describe('ChatView message.delta handling', () => {
})
})
describe('ChatView markdown rendering', () => {
beforeEach(() => {
localStorage.clear()
vi.clearAllMocks()
latestEventSource = null
globalThis.EventSource = MockEventSource
globalThis.scrollTo = vi.fn()
})
it('renders markdown content and mermaid blocks', async () => {
localStorage.setItem('ars-token', 'token')
const router = makeRouter()
router.push('/chat/session-1')
await router.isReady()
const markdownText = ['Hello **world**', '', '```mermaid', 'graph TD;', 'A-->B;', '```'].join(
'\n'
)
const list = [
buildMessage({
seq: 1,
role: 'AGENT',
type: 'agent.message',
content: markdownText,
}),
]
mockedAxios.get.mockImplementation((url) => {
if (url.endsWith('/sessions/session-1')) {
return Promise.resolve({
data: { session_name: 'Demo', status: 'OPEN', last_seq: 1 },
})
}
if (url.endsWith('/sessions/session-1/messages')) {
return Promise.resolve({ data: { data: list } })
}
return Promise.resolve({ data: {} })
})
const wrapper = mount(ChatView, {
global: {
plugins: [router, ElementPlus],
},
})
await flushPromises()
await nextTick()
const bubble = wrapper.find('.bubble-agent')
expect(bubble.exists()).toBe(true)
const textBlock = bubble.find('.bubble-text')
expect(textBlock.html()).toContain('<strong>world</strong>')
const mermaidBlock = textBlock.find('.mermaid')
expect(mermaidBlock.exists()).toBe(true)
expect(mermaidBlock.text()).toContain('A-->B')
})
})
describe('ChatView system error and failed status handling', () => {
beforeEach(() => {
localStorage.clear()