diff --git a/src/lib/export/html.ts b/src/lib/export/html.ts
new file mode 100644
index 0000000..3858399
--- /dev/null
+++ b/src/lib/export/html.ts
@@ -0,0 +1,1236 @@
+/**
+ * HTML 导出器
+ * 将对话数据导出为完整的 HTML 文件
+ * 设计主题:LionCode 橙色 (#DB6639)
+ */
+
+import type { ExportData, ExportOptions, ExportMessageData, Exporter } from './types';
+
+// 工具名称中文映射
+const TOOL_NAMES: Record
');
+
+ // 行内代码
+ html = html.replace(/`([^`]+)`/g, '$2$1');
+
+ // 粗体
+ html = html.replace(/\*\*(.+?)\*\*/g, '$1');
+
+ // 斜体
+ html = html.replace(/\*(.+?)\*/g, '$1');
+
+ // 链接
+ html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '$1');
+
+ // 标题(从h6到h1,避免误匹配)
+ html = html.replace(/^###### (.+)$/gm, '$1
');
+ html = html.replace(/^##### (.+)$/gm, '$1
');
+ html = html.replace(/^#### (.+)$/gm, '$1
');
+ html = html.replace(/^### (.+)$/gm, '$1
');
+ html = html.replace(/^## (.+)$/gm, '$1
');
+ html = html.replace(/^# (.+)$/gm, '$1
');
+
+ // 列表
+ html = html.replace(/^- (.+)$/gm, '$&
');
+
+ // 段落
+ html = html.replace(/\n\n/g, '
'); + html = '
' + html + '
'; + html = html.replace(/<\/p>/g, ''); + html = html.replace(/
( ( ()/g, '$1');
+ html = html.replace(/(<\/ul>)<\/p>/g, '$1');
+ html = html.replace(/
)/g, '$1');
+ html = html.replace(/(<\/pre>)<\/p>/g, '$1');
+
+ return html;
+}
+
+/**
+ * 生成消息 HTML
+ */
+function generateMessageHtml(
+ message: ExportMessageData,
+ options: ExportOptions
+): string {
+ const isUser = message.role === 'user';
+ const roleClass = isUser ? 'user-message' : 'assistant-message';
+ const time = formatTime(message.createdAt);
+
+ let html = ``;
+ return html;
+}
+
+/**
+ * 生成完整的 HTML 样式 - LionCode 主题
+ */
+function generateStyles(): string {
+ return `
+ /* ========================================
+ LionCode HTML Export Theme
+ Primary Color: #DB6639 (LionCode Orange)
+ ======================================== */
+
+ :root {
+ /* 主色调 */
+ --primary: #DB6639;
+ --primary-light: #F4D9CF;
+ --primary-lighter: #FDF5F2;
+ --primary-dark: #C25A33;
+ --primary-darker: #A84D2B;
+
+ /* 浅色模式 */
+ --bg-page: #F8F9FA;
+ --bg-card: #FFFFFF;
+ --bg-secondary: #F3F4F6;
+ --bg-tertiary: #E5E7EB;
+ --bg-user-bubble: #E8E8E6;
+ --bg-ai-message: #FFFFFF;
+
+ --text-primary: #1F2937;
+ --text-secondary: #4B5563;
+ --text-tertiary: #9CA3AF;
+ --text-inverse: #FFFFFF;
+
+ --border-color: #E5E7EB;
+ --border-light: #F3F4F6;
+
+ /* 思考区域 */
+ --thinking-bg: #FDF5F2;
+ --thinking-border: #F4D9CF;
+
+ /* 代码区域 */
+ --code-bg: #1E293B;
+ --code-text: #E2E8F0;
+ --code-inline-bg: #F1F5F9;
+ --code-inline-text: #334155;
+
+ /* 阴影 */
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1);
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -4px rgba(0, 0, 0, 0.1);
+ }
+
+ @media (prefers-color-scheme: dark) {
+ :root {
+ --bg-page: #0F172A;
+ --bg-card: #1E293B;
+ --bg-secondary: #334155;
+ --bg-tertiary: #475569;
+ --bg-user-bubble: #334155;
+ --bg-ai-message: #1E293B;
+
+ --text-primary: #F1F5F9;
+ --text-secondary: #CBD5E1;
+ --text-tertiary: #64748B;
+ --text-inverse: #FFFFFF;
+
+ --border-color: #334155;
+ --border-light: #475569;
+
+ --thinking-bg: #2D1F1A;
+ --thinking-border: #5C3D2E;
+
+ --code-bg: #0D1117;
+ --code-text: #E6EDF3;
+ --code-inline-bg: #334155;
+ --code-inline-text: #E2E8F0;
+ }
+ }
+
+ * {
+ margin: 0;
+ padding: 0;
+ box-sizing: border-box;
+ }
+
+ body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
+ font-size: 15px;
+ line-height: 1.7;
+ background-color: var(--bg-page);
+ color: var(--text-primary);
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ }
+
+ .container {
+ max-width: 900px;
+ margin: 0 auto;
+ padding: 24px;
+ }
+
+ /* ======== 头部区域 ======== */
+ header {
+ background: linear-gradient(135deg, var(--primary) 0%, var(--primary-dark) 100%);
+ color: var(--text-inverse);
+ padding: 16px 20px;
+ border-radius: 10px;
+ margin-bottom: 20px;
+ box-shadow: var(--shadow-md);
+ position: relative;
+ overflow: hidden;
+ }
+
+ header::before {
+ content: '';
+ position: absolute;
+ top: -50%;
+ right: -20%;
+ width: 200px;
+ height: 200px;
+ background: radial-gradient(circle, rgba(255,255,255,0.06) 0%, transparent 70%);
+ pointer-events: none;
+ }
+
+ .header-brand {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ margin-bottom: 8px;
+ }
+
+ .brand-logo {
+ width: 28px;
+ height: 28px;
+ background: rgba(255, 255, 255, 0.2);
+ border-radius: 6px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 14px;
+ backdrop-filter: blur(4px);
+ }
+
+ .brand-text {
+ font-size: 12px;
+ font-weight: 500;
+ opacity: 0.9;
+ }
+
+ header h1 {
+ font-size: 16px;
+ font-weight: 600;
+ margin-bottom: 12px;
+ line-height: 1.4;
+ position: relative;
+ }
+
+ .meta-cards {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ gap: 8px;
+ }
+
+ .meta-card {
+ background: rgba(255, 255, 255, 0.12);
+ backdrop-filter: blur(4px);
+ padding: 8px 10px;
+ border-radius: 6px;
+ }
+
+ .meta-card-label {
+ font-size: 10px;
+ opacity: 0.75;
+ margin-bottom: 2px;
+ }
+
+ .meta-card-value {
+ font-size: 12px;
+ font-weight: 600;
+ }
+
+ /* ======== 消息区域 ======== */
+ main {
+ display: flex;
+ flex-direction: column;
+ gap: 20px;
+ }
+
+ .message {
+ border-radius: 12px;
+ overflow: hidden;
+ box-shadow: var(--shadow-sm);
+ }
+
+ /* 用户消息 - 模仿原聊天界面样式 */
+ .user-message {
+ display: flex;
+ flex-direction: row;
+ align-items: flex-start;
+ gap: 12px;
+ background: transparent;
+ box-shadow: none;
+ margin-left: 80px;
+ }
+
+ .user-message .message-wrapper {
+ flex: 1;
+ background: var(--bg-user-bubble);
+ border-radius: 12px;
+ overflow: hidden;
+ }
+
+ .user-message .message-header {
+ display: none;
+ }
+
+ .user-message .user-avatar-right {
+ width: 40px;
+ height: 40px;
+ border-radius: 50%;
+ background: var(--primary);
+ color: white;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 16px;
+ font-weight: 600;
+ flex-shrink: 0;
+ }
+
+ .user-message .message-body {
+ padding: 14px 16px;
+ }
+
+ .user-message .message-content {
+ color: var(--text-primary);
+ }
+
+ .user-message .message-content a {
+ color: var(--primary);
+ }
+
+ .user-message .message-content code {
+ background: rgba(0, 0, 0, 0.06);
+ color: var(--text-primary);
+ }
+
+ /* AI 消息 - 移除左侧边框 */
+ .assistant-message {
+ background: var(--bg-ai-message);
+ border: 1px solid var(--border-color);
+ margin-right: 80px;
+ }
+
+ .assistant-message .message-header {
+ background: var(--bg-secondary);
+ border-bottom: 1px solid var(--border-color);
+ }
+
+ /* 消息头部 */
+ .message-header {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 14px 18px;
+ }
+
+ .avatar {
+ width: 32px;
+ height: 32px;
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 14px;
+ font-weight: 600;
+ flex-shrink: 0;
+ }
+
+ .user-avatar {
+ background: rgba(255, 255, 255, 0.25);
+ }
+
+ .ai-avatar {
+ background: var(--primary);
+ color: white;
+ }
+
+ .ai-avatar svg {
+ width: 18px;
+ height: 18px;
+ }
+
+ .role-name {
+ font-weight: 600;
+ font-size: 14px;
+ color: var(--text-primary);
+ }
+
+ .message-time {
+ margin-left: auto;
+ font-size: 12px;
+ color: var(--text-tertiary);
+ }
+
+ /* 消息内容区 */
+ .message-body {
+ padding: 18px;
+ }
+
+ .message-content {
+ color: var(--text-primary);
+ line-height: 1.8;
+ }
+
+ .message-content p {
+ margin-bottom: 14px;
+ }
+
+ .message-content p:last-child {
+ margin-bottom: 0;
+ }
+
+ .message-content h1,
+ .message-content h2,
+ .message-content h3,
+ .message-content h4,
+ .message-content h5,
+ .message-content h6 {
+ margin: 20px 0 12px;
+ color: var(--text-primary);
+ font-weight: 600;
+ }
+
+ .message-content h1 { font-size: 1.5em; }
+ .message-content h2 { font-size: 1.35em; }
+ .message-content h3 { font-size: 1.2em; }
+ .message-content h4 { font-size: 1.1em; }
+ .message-content h5 { font-size: 1.05em; }
+ .message-content h6 { font-size: 1em; color: var(--text-secondary); }
+
+ .message-content code {
+ background: var(--code-inline-bg);
+ color: var(--code-inline-text);
+ padding: 2px 8px;
+ border-radius: 4px;
+ font-family: 'SF Mono', 'Monaco', 'Menlo', 'Consolas', monospace;
+ font-size: 0.9em;
+ }
+
+ .message-content pre {
+ background: var(--code-bg);
+ color: var(--code-text);
+ padding: 18px;
+ border-radius: 10px;
+ overflow-x: auto;
+ margin: 16px 0;
+ font-family: 'SF Mono', 'Monaco', 'Menlo', 'Consolas', monospace;
+ font-size: 13px;
+ line-height: 1.6;
+ }
+
+ .message-content pre code {
+ background: none;
+ padding: 0;
+ color: inherit;
+ }
+
+ .message-content ul,
+ .message-content ol {
+ margin: 12px 0;
+ padding-left: 24px;
+ }
+
+ .message-content li {
+ margin-bottom: 6px;
+ }
+
+ .message-content a {
+ color: var(--primary);
+ text-decoration: none;
+ font-weight: 500;
+ }
+
+ .message-content a:hover {
+ text-decoration: underline;
+ }
+
+ .message-content strong {
+ font-weight: 600;
+ }
+
+ /* ======== 工具标签 ======== */
+ .tools-used {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ margin-bottom: 14px;
+ }
+
+ .tool-badge {
+ display: inline-flex;
+ align-items: center;
+ gap: 4px;
+ padding: 5px 12px;
+ background: var(--primary-lighter);
+ color: var(--primary-dark);
+ border-radius: 20px;
+ font-size: 12px;
+ font-weight: 500;
+ border: 1px solid var(--primary-light);
+ }
+
+ /* ======== 思考区域 ======== */
+ .thinking-section {
+ margin: 14px 0;
+ background: var(--thinking-bg);
+ border: 1px solid var(--thinking-border);
+ border-radius: 10px;
+ overflow: hidden;
+ }
+
+ .thinking-section summary {
+ padding: 12px 16px;
+ cursor: pointer;
+ font-weight: 500;
+ color: var(--primary);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ user-select: none;
+ }
+
+ .thinking-section summary:hover {
+ background: var(--primary-light);
+ }
+
+ .thinking-section summary::marker,
+ .thinking-section summary::-webkit-details-marker {
+ display: none;
+ }
+
+ .thinking-section summary::before {
+ content: '▶';
+ font-size: 10px;
+ transition: transform 0.2s ease;
+ }
+
+ .thinking-section[open] summary::before {
+ transform: rotate(90deg);
+ }
+
+ .thinking-icon {
+ font-size: 16px;
+ }
+
+ .thinking-content {
+ padding: 16px;
+ font-size: 13px;
+ line-height: 1.7;
+ color: var(--text-secondary);
+ white-space: pre-wrap;
+ word-wrap: break-word;
+ border-top: 1px solid var(--thinking-border);
+ background: rgba(255, 255, 255, 0.5);
+ }
+
+ @media (prefers-color-scheme: dark) {
+ .thinking-content {
+ background: rgba(0, 0, 0, 0.2);
+ }
+ }
+
+ /* ======== 工具调用详情 ======== */
+ .tool-calls-section {
+ margin: 14px 0;
+ background: var(--bg-secondary);
+ border: 1px solid var(--border-color);
+ border-radius: 10px;
+ overflow: hidden;
+ }
+
+ .tool-calls-section summary {
+ padding: 12px 16px;
+ cursor: pointer;
+ font-weight: 500;
+ color: var(--text-secondary);
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ }
+
+ .tool-calls-section summary:hover {
+ background: var(--bg-tertiary);
+ }
+
+ .tool-calls-section summary::marker,
+ .tool-calls-section summary::-webkit-details-marker {
+ display: none;
+ }
+
+ .tool-calls-section summary::before {
+ content: '▶';
+ font-size: 10px;
+ transition: transform 0.2s ease;
+ }
+
+ .tool-calls-section[open] summary::before {
+ transform: rotate(90deg);
+ }
+
+ .tool-icon {
+ font-size: 16px;
+ }
+
+ .tool-calls {
+ padding: 16px;
+ border-top: 1px solid var(--border-color);
+ }
+
+ .tool-call {
+ margin-bottom: 16px;
+ }
+
+ .tool-call:last-child {
+ margin-bottom: 0;
+ }
+
+ .tool-call-header {
+ font-weight: 600;
+ font-size: 13px;
+ margin-bottom: 8px;
+ color: var(--text-primary);
+ }
+
+ .tool-call-input {
+ background: var(--code-bg);
+ color: var(--code-text);
+ padding: 14px;
+ border-radius: 8px;
+ font-size: 12px;
+ line-height: 1.5;
+ overflow-x: auto;
+ }
+
+ /* ======== 附件区域 ======== */
+ .attachment-section,
+ .result-section {
+ margin: 12px 0;
+ padding: 14px;
+ background: rgba(255, 255, 255, 0.5);
+ border-radius: 10px;
+ border: 1px solid rgba(0, 0, 0, 0.08);
+ }
+
+ @media (prefers-color-scheme: dark) {
+ .attachment-section,
+ .result-section {
+ background: rgba(0, 0, 0, 0.2);
+ border-color: rgba(255, 255, 255, 0.08);
+ }
+ }
+
+ .user-message .attachment-section {
+ background: rgba(0, 0, 0, 0.1);
+ border-color: rgba(255, 255, 255, 0.1);
+ }
+
+ .attachment-title,
+ .result-title {
+ font-weight: 600;
+ font-size: 13px;
+ margin-bottom: 10px;
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ }
+
+ .user-message .attachment-title {
+ color: rgba(255, 255, 255, 0.9);
+ }
+
+ .attachment-icon,
+ .result-icon {
+ font-size: 14px;
+ }
+
+ /* 图片网格 */
+ .images-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
+ gap: 12px;
+ }
+
+ .uploaded-image,
+ .code-image {
+ width: 100%;
+ height: auto;
+ max-height: 240px;
+ object-fit: contain;
+ border-radius: 8px;
+ background: var(--bg-secondary);
+ }
+
+ .user-message .uploaded-image {
+ background: rgba(0, 0, 0, 0.2);
+ }
+
+ /* 搜索图片 */
+ .search-images-grid {
+ grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
+ }
+
+ .search-image-link {
+ display: flex;
+ flex-direction: column;
+ text-decoration: none;
+ background: var(--bg-secondary);
+ border-radius: 8px;
+ overflow: hidden;
+ transition: transform 0.2s ease, box-shadow 0.2s ease;
+ }
+
+ .search-image-link:hover {
+ transform: translateY(-2px);
+ box-shadow: var(--shadow-md);
+ }
+
+ .search-image {
+ width: 100%;
+ height: 120px;
+ object-fit: cover;
+ }
+
+ .search-image-title {
+ padding: 8px 10px;
+ font-size: 12px;
+ color: var(--text-secondary);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ /* 文档列表 */
+ .document-list {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+ }
+
+ .document-item {
+ display: flex;
+ align-items: center;
+ gap: 10px;
+ padding: 10px 12px;
+ background: rgba(255, 255, 255, 0.6);
+ border-radius: 8px;
+ }
+
+ .user-message .document-item {
+ background: rgba(0, 0, 0, 0.15);
+ }
+
+ .doc-icon {
+ font-size: 16px;
+ flex-shrink: 0;
+ }
+
+ .doc-name {
+ font-weight: 500;
+ flex: 1;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ }
+
+ .doc-size {
+ font-size: 12px;
+ opacity: 0.7;
+ flex-shrink: 0;
+ }
+
+ /* ======== Token 统计 ======== */
+ .token-stats {
+ margin-top: 14px;
+ padding: 10px 14px;
+ background: var(--bg-secondary);
+ border-radius: 8px;
+ font-size: 12px;
+ color: var(--text-tertiary);
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ }
+
+ .token-label {
+ font-weight: 500;
+ }
+
+ .token-value {
+ color: var(--text-secondary);
+ }
+
+ .token-divider {
+ opacity: 0.5;
+ }
+
+ /* ======== 页脚 ======== */
+ footer {
+ margin-top: 24px;
+ padding: 16px 20px;
+ background: var(--bg-card);
+ border: 1px solid var(--border-color);
+ border-radius: 10px;
+ text-align: center;
+ }
+
+ .footer-brand {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ margin-bottom: 6px;
+ }
+
+ .footer-logo {
+ width: 22px;
+ height: 22px;
+ background: var(--primary);
+ border-radius: 5px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 11px;
+ }
+
+ .footer-title {
+ font-weight: 600;
+ font-size: 13px;
+ color: var(--text-primary);
+ }
+
+ .footer-desc {
+ font-size: 12px;
+ color: var(--text-tertiary);
+ margin-bottom: 4px;
+ }
+
+ .footer-link {
+ color: var(--primary);
+ text-decoration: none;
+ font-weight: 500;
+ font-size: 12px;
+ }
+
+ .footer-link:hover {
+ text-decoration: underline;
+ }
+
+ /* ======== 打印样式 ======== */
+ @media print {
+ body {
+ background: white;
+ -webkit-print-color-adjust: exact;
+ print-color-adjust: exact;
+ }
+
+ .container {
+ max-width: 100%;
+ padding: 0;
+ }
+
+ header {
+ border-radius: 0;
+ margin-bottom: 24px;
+ box-shadow: none;
+ }
+
+ .message {
+ break-inside: avoid;
+ page-break-inside: avoid;
+ box-shadow: none;
+ }
+
+ .thinking-section,
+ .tool-calls-section {
+ break-inside: avoid;
+ page-break-inside: avoid;
+ }
+
+ footer {
+ border-radius: 0;
+ margin-top: 24px;
+ }
+
+ .user-message {
+ margin-left: 40px;
+ }
+
+ .assistant-message {
+ margin-right: 40px;
+ }
+ }
+
+ /* ======== 响应式设计 ======== */
+ @media (max-width: 640px) {
+ .container {
+ padding: 16px;
+ }
+
+ header {
+ padding: 20px;
+ border-radius: 10px;
+ }
+
+ header h1 {
+ font-size: 18px;
+ }
+
+ .meta-cards {
+ grid-template-columns: repeat(2, 1fr);
+ gap: 8px;
+ }
+
+ .meta-card {
+ padding: 8px 10px;
+ }
+
+ .meta-card-value {
+ font-size: 13px;
+ }
+
+ .user-message {
+ margin-left: 20px;
+ }
+
+ .assistant-message {
+ margin-right: 20px;
+ }
+
+ .message-header {
+ padding: 10px 12px;
+ }
+
+ .message-body {
+ padding: 12px;
+ }
+
+ .images-grid {
+ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
+ gap: 8px;
+ }
+
+ .user-avatar-right {
+ width: 32px;
+ height: 32px;
+ font-size: 14px;
+ }
+ }
+ `;
+}
+
+/**
+ * HTML 导出器
+ */
+export const htmlExporter: Exporter = {
+ async export(data: ExportData, options: ExportOptions): Promise${escapeHtml(conversation.title)}
\n`;
+ html += '\n';
+ html += '💭 思考过程
');
+ lines.push('');
+ lines.push('```');
+ lines.push(message.thinkingContent);
+ lines.push('```');
+ lines.push('');
+ lines.push('🛠️ 工具调用详情
');
+ lines.push('');
+ message.toolCalls.forEach((call, index) => {
+ lines.push(`**调用 ${index + 1}: ${TOOL_NAMES[call.name] || call.name}**`);
+ lines.push('```json');
+ lines.push(JSON.stringify(call.input, null, 2));
+ lines.push('```');
+ lines.push('');
+ });
+ lines.push('