fix: 暗色主题优化,优化ai对话
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, nextTick, onUnmounted, ref, watch } from 'vue';
|
|
||||||
import { storeToRefs } from 'pinia';
|
|
||||||
import { marked } from 'marked';
|
|
||||||
import hljs from 'highlight.js';
|
|
||||||
import DOMPurify from 'dompurify';
|
import DOMPurify from 'dompurify';
|
||||||
import { ElDrawer } from 'element-plus';
|
import { ElDrawer } from 'element-plus';
|
||||||
|
import hljs from 'highlight.js';
|
||||||
|
import { marked } from 'marked';
|
||||||
|
import { storeToRefs } from 'pinia';
|
||||||
|
import { computed, nextTick, onUnmounted, ref, watch } from 'vue';
|
||||||
import { useDesignStore } from '@/stores';
|
import { useDesignStore } from '@/stores';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -44,7 +44,8 @@ const renderer = {
|
|||||||
let highlighted: string;
|
let highlighted: string;
|
||||||
try {
|
try {
|
||||||
highlighted = hljs.highlight(text, { language: validLanguage, ignoreIllegals: true }).value;
|
highlighted = hljs.highlight(text, { language: validLanguage, ignoreIllegals: true }).value;
|
||||||
} catch {
|
}
|
||||||
|
catch {
|
||||||
highlighted = hljs.highlightAuto(text).value;
|
highlighted = hljs.highlightAuto(text).value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +59,8 @@ const renderer = {
|
|||||||
const isHtml = lang?.toLowerCase() === 'html' || lang?.toLowerCase() === 'htm';
|
const isHtml = lang?.toLowerCase() === 'html' || lang?.toLowerCase() === 'htm';
|
||||||
|
|
||||||
// 预览按钮(仅HTML显示)
|
// 预览按钮(仅HTML显示)
|
||||||
const previewBtn = isHtml ? `
|
const previewBtn = isHtml
|
||||||
|
? `
|
||||||
<button class="preview-btn" data-html="${encodeURIComponent(text)}">
|
<button class="preview-btn" data-html="${encodeURIComponent(text)}">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
|
||||||
@@ -66,7 +68,8 @@ const renderer = {
|
|||||||
</svg>
|
</svg>
|
||||||
<span>预览</span>
|
<span>预览</span>
|
||||||
</button>
|
</button>
|
||||||
` : '';
|
`
|
||||||
|
: '';
|
||||||
|
|
||||||
return `<div class="code-block-wrapper${isHtml ? ' is-html' : ''}">
|
return `<div class="code-block-wrapper${isHtml ? ' is-html' : ''}">
|
||||||
<div class="code-block-header">
|
<div class="code-block-header">
|
||||||
@@ -155,7 +158,8 @@ async function renderContent(content: string) {
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
bindButtons();
|
bindButtons();
|
||||||
});
|
});
|
||||||
} catch (error) {
|
}
|
||||||
|
catch (error) {
|
||||||
console.error('Markdown 渲染错误:', error);
|
console.error('Markdown 渲染错误:', error);
|
||||||
renderedHtml.value = `<pre>${content}</pre>`;
|
renderedHtml.value = `<pre>${content}</pre>`;
|
||||||
}
|
}
|
||||||
@@ -163,7 +167,8 @@ async function renderContent(content: string) {
|
|||||||
|
|
||||||
// 绑定按钮事件
|
// 绑定按钮事件
|
||||||
function bindButtons() {
|
function bindButtons() {
|
||||||
if (!containerRef.value) return;
|
if (!containerRef.value)
|
||||||
|
return;
|
||||||
|
|
||||||
// 绑定复制按钮
|
// 绑定复制按钮
|
||||||
const copyButtons = containerRef.value.querySelectorAll('.copy-btn');
|
const copyButtons = containerRef.value.querySelectorAll('.copy-btn');
|
||||||
@@ -188,7 +193,8 @@ function bindButtons() {
|
|||||||
newBtn.classList.remove('copied');
|
newBtn.classList.remove('copied');
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
}
|
||||||
|
catch (err) {
|
||||||
console.error('复制失败:', err);
|
console.error('复制失败:', err);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -246,7 +252,7 @@ watch(
|
|||||||
(newContent) => {
|
(newContent) => {
|
||||||
scheduleRender(newContent);
|
scheduleRender(newContent);
|
||||||
},
|
},
|
||||||
{ immediate: true }
|
{ immediate: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
// 暴露方法供外部调用
|
// 暴露方法供外部调用
|
||||||
@@ -630,68 +636,7 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// highlight.js 深色主题样式
|
// 深色主题代码高亮样式已移至 dark-theme.scss,使用 [data-theme="dark"] 选择器
|
||||||
.marked-markdown.theme-dark {
|
|
||||||
.hljs {
|
|
||||||
color: #c9d1d9;
|
|
||||||
}
|
|
||||||
.hljs-comment,
|
|
||||||
.hljs-quote {
|
|
||||||
color: #8b949e;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.hljs-keyword,
|
|
||||||
.hljs-selector-tag,
|
|
||||||
.hljs-addition {
|
|
||||||
color: #ff7b72;
|
|
||||||
}
|
|
||||||
.hljs-number,
|
|
||||||
.hljs-string,
|
|
||||||
.hljs-meta .hljs-meta-string,
|
|
||||||
.hljs-literal,
|
|
||||||
.hljs-doctag,
|
|
||||||
.hljs-regexp {
|
|
||||||
color: #a5d6ff;
|
|
||||||
}
|
|
||||||
.hljs-title,
|
|
||||||
.hljs-section,
|
|
||||||
.hljs-name,
|
|
||||||
.hljs-selector-id,
|
|
||||||
.hljs-selector-class {
|
|
||||||
color: #d2a8ff;
|
|
||||||
}
|
|
||||||
.hljs-attribute,
|
|
||||||
.hljs-attr,
|
|
||||||
.hljs-variable,
|
|
||||||
.hljs-template-variable,
|
|
||||||
.hljs-class .hljs-title,
|
|
||||||
.hljs-type {
|
|
||||||
color: #79c0ff;
|
|
||||||
}
|
|
||||||
.hljs-symbol,
|
|
||||||
.hljs-bullet,
|
|
||||||
.hljs-subst,
|
|
||||||
.hljs-meta,
|
|
||||||
.hljs-meta .hljs-keyword,
|
|
||||||
.hljs-selector-attr,
|
|
||||||
.hljs-selector-pseudo,
|
|
||||||
.hljs-link {
|
|
||||||
color: #ffa657;
|
|
||||||
}
|
|
||||||
.hljs-built_in,
|
|
||||||
.hljs-deletion {
|
|
||||||
color: #ffa198;
|
|
||||||
}
|
|
||||||
.hljs-formula {
|
|
||||||
background-color: #21262d;
|
|
||||||
}
|
|
||||||
.hljs-emphasis {
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.hljs-strong {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// highlight.js 浅色主题样式
|
// highlight.js 浅色主题样式
|
||||||
.marked-markdown.theme-light {
|
.marked-markdown.theme-light {
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
/* ========== 深色主题 Element Plus 覆盖样式 ========== */
|
/* ========== 深色主题 Element Plus 覆盖样式 ========== */
|
||||||
|
.body {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
/* 深色主题通用 Div 样式 Mixin */
|
/* 深色主题通用 Div 样式 Mixin */
|
||||||
@mixin dark-theme-div {
|
@mixin dark-theme-div {
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
@@ -205,7 +207,7 @@
|
|||||||
box-shadow: 0 10px 25px rgba(0, 255, 136, 0.3) !important;
|
box-shadow: 0 10px 25px rgba(0, 255, 136, 0.3) !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 主要按钮 */
|
/* 主要按钮 */
|
||||||
.el-button--primary {
|
.el-button--primary {
|
||||||
background-color: #00d36e !important;
|
background-color: #00d36e !important;
|
||||||
@@ -352,7 +354,7 @@
|
|||||||
|
|
||||||
td.el-table__cell {
|
td.el-table__cell {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
@@ -365,7 +367,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.el-table__row {
|
.el-table__row {
|
||||||
|
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -576,10 +578,46 @@
|
|||||||
color: #a0a0a0 !important;
|
color: #a0a0a0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
/* 行内代码 */
|
||||||
|
code:not(pre code) {
|
||||||
color: #00ff88 !important;
|
color: #00ff88 !important;
|
||||||
background-color: rgba(0, 255, 136, 0.1) !important;
|
background-color: rgba(0, 255, 136, 0.1) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 代码块内的代码高亮 - 不覆盖颜色 */
|
||||||
|
pre code,
|
||||||
|
.hljs,
|
||||||
|
.hljs * {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 代码高亮特定 token 颜色 */
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag {
|
||||||
|
color: #ff7b72 !important;
|
||||||
|
}
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-number {
|
||||||
|
color: #a5d6ff !important;
|
||||||
|
}
|
||||||
|
.hljs-name,
|
||||||
|
.hljs-title {
|
||||||
|
color: #d2a8ff !important;
|
||||||
|
}
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-variable {
|
||||||
|
color: #79c0ff !important;
|
||||||
|
}
|
||||||
|
.hljs-tag {
|
||||||
|
color: #7ee787 !important;
|
||||||
|
}
|
||||||
|
.hljs-punctuation {
|
||||||
|
color: #bdc3cf !important;
|
||||||
|
}
|
||||||
|
.hljs-comment {
|
||||||
|
color: #7d8590 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -748,13 +786,75 @@
|
|||||||
background-color: #04080b !important;
|
background-color: #04080b !important;
|
||||||
color: #a0a0a0 !important;
|
color: #a0a0a0 !important;
|
||||||
border: 1px solid rgba(0, 255, 136, 0.15) !important;
|
border: 1px solid rgba(0, 255, 136, 0.15) !important;
|
||||||
|
|
||||||
|
/* 代码高亮元素颜色覆盖 - 确保.hljs类颜色不被父元素覆盖 */
|
||||||
|
.hljs,
|
||||||
|
.hljs * {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 为不同代码元素设置特定颜色 */
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-addition {
|
||||||
|
color: #ff7b72 !important;
|
||||||
|
}
|
||||||
|
.hljs-number,
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-regexp {
|
||||||
|
color: #a5d6ff !important;
|
||||||
|
}
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-section,
|
||||||
|
.hljs-name {
|
||||||
|
color: #d2a8ff !important;
|
||||||
|
}
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-type {
|
||||||
|
color: #79c0ff !important;
|
||||||
|
}
|
||||||
|
.hljs-tag {
|
||||||
|
color: #7ee787 !important;
|
||||||
|
}
|
||||||
|
.hljs-tag .hljs-name {
|
||||||
|
color: #7ee787 !important;
|
||||||
|
}
|
||||||
|
.hljs-tag .hljs-attr {
|
||||||
|
color: #79c0ff !important;
|
||||||
|
}
|
||||||
|
.hljs-tag .hljs-string {
|
||||||
|
color: #a5d6ff !important;
|
||||||
|
}
|
||||||
|
.hljs-punctuation {
|
||||||
|
color: #bdc3cf !important;
|
||||||
|
}
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-quote {
|
||||||
|
color: #7d8590 !important;
|
||||||
|
}
|
||||||
|
.hljs-built_in {
|
||||||
|
color: #ffa198 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 用户气泡 */
|
/* 用户气泡 */
|
||||||
.el-bubble[data-placement="end"] .el-bubble-content,
|
.el-bubble[data-placement="end"] .el-bubble-content,
|
||||||
.el-bubble--end .el-bubble-content {
|
.el-bubble--end .el-bubble-content {
|
||||||
background-color: #00d36e !important;
|
background-color: transparent !important;
|
||||||
color: #000000 !important;
|
}
|
||||||
|
|
||||||
|
/* 用户消息内容 - MessageItem.vue */
|
||||||
|
.message-content--user {
|
||||||
|
background-color: #30363d !important;
|
||||||
|
color: #e6edf3 !important;
|
||||||
|
border: 1px solid rgba(0, 255, 136, 0.3) !important;
|
||||||
|
|
||||||
|
.message-content__text {
|
||||||
|
color: #e6edf3 !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 用户文件项 */
|
/* 用户文件项 */
|
||||||
@@ -771,6 +871,162 @@
|
|||||||
border-color: rgba(0, 255, 136, 0.15) !important;
|
border-color: rgba(0, 255, 136, 0.15) !important;
|
||||||
color: #666 !important;
|
color: #666 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* MarkedMarkdown 完整暗色主题覆盖 */
|
||||||
|
.marked-markdown,
|
||||||
|
.marked-markdown.theme-light {
|
||||||
|
/* 基础文本颜色 - 覆盖 .theme-light 的 color: #24292f */
|
||||||
|
color: #e6edf3 !important;
|
||||||
|
|
||||||
|
/* 链接 */
|
||||||
|
a {
|
||||||
|
color: #58a6ff !important;
|
||||||
|
&:hover {
|
||||||
|
color: #79c0ff !important;
|
||||||
|
text-decoration: underline !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标题 */
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
color: #ffffff !important;
|
||||||
|
border-bottom-color: #30363d !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 分割线 */
|
||||||
|
hr {
|
||||||
|
background-color: #30363d !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 引用块 */
|
||||||
|
blockquote {
|
||||||
|
color: #8b949e !important;
|
||||||
|
border-left-color: #30363d !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 行内代码 */
|
||||||
|
code.inline-code {
|
||||||
|
background-color: rgba(110, 118, 129, 0.4) !important;
|
||||||
|
color: #e6edf3 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 代码块 */
|
||||||
|
.code-block-wrapper {
|
||||||
|
background-color: #161b22 !important;
|
||||||
|
border-color: #30363d !important;
|
||||||
|
|
||||||
|
.code-block-header {
|
||||||
|
background-color: #161b22 !important;
|
||||||
|
border-bottom-color: #30363d !important;
|
||||||
|
|
||||||
|
.code-lang {
|
||||||
|
color: #8b949e !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-btn,
|
||||||
|
.preview-btn {
|
||||||
|
color: #8b949e !important;
|
||||||
|
&:hover {
|
||||||
|
color: #e6edf3 !important;
|
||||||
|
background-color: #30363d !important;
|
||||||
|
}
|
||||||
|
&.copied {
|
||||||
|
color: #3fb950 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-block-body {
|
||||||
|
.line-numbers {
|
||||||
|
background-color: #161b22 !important;
|
||||||
|
border-right-color: #30363d !important;
|
||||||
|
|
||||||
|
.line-number {
|
||||||
|
color: #6e7681 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pre.hljs {
|
||||||
|
background-color: #161b22 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 表格 */
|
||||||
|
table {
|
||||||
|
th, td {
|
||||||
|
border-color: #30363d !important;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: #161b22 !important;
|
||||||
|
}
|
||||||
|
tr:nth-child(2n) {
|
||||||
|
background-color: #161b22 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确保子元素继承正确颜色 */
|
||||||
|
p, li, td, th {
|
||||||
|
color: #e6edf3 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 代码高亮元素颜色覆盖 - 确保.hljs类颜色不被父元素覆盖 */
|
||||||
|
.hljs,
|
||||||
|
.hljs * {
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 基础文本 */
|
||||||
|
.hljs {
|
||||||
|
color: #e6edf3 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 为不同代码元素设置特定颜色 */
|
||||||
|
.hljs-keyword,
|
||||||
|
.hljs-selector-tag,
|
||||||
|
.hljs-addition {
|
||||||
|
color: #ff7b72 !important;
|
||||||
|
}
|
||||||
|
.hljs-number,
|
||||||
|
.hljs-string,
|
||||||
|
.hljs-literal,
|
||||||
|
.hljs-regexp {
|
||||||
|
color: #a5d6ff !important;
|
||||||
|
}
|
||||||
|
.hljs-title,
|
||||||
|
.hljs-section,
|
||||||
|
.hljs-name {
|
||||||
|
color: #d2a8ff !important;
|
||||||
|
}
|
||||||
|
.hljs-attribute,
|
||||||
|
.hljs-attr,
|
||||||
|
.hljs-variable,
|
||||||
|
.hljs-type {
|
||||||
|
color: #79c0ff !important;
|
||||||
|
}
|
||||||
|
.hljs-tag {
|
||||||
|
color: #7ee787 !important;
|
||||||
|
}
|
||||||
|
.hljs-tag .hljs-name {
|
||||||
|
color: #7ee787 !important;
|
||||||
|
}
|
||||||
|
.hljs-tag .hljs-attr {
|
||||||
|
color: #79c0ff !important;
|
||||||
|
}
|
||||||
|
.hljs-tag .hljs-string {
|
||||||
|
color: #a5d6ff !important;
|
||||||
|
}
|
||||||
|
.hljs-punctuation {
|
||||||
|
color: #bdc3cf !important;
|
||||||
|
}
|
||||||
|
.hljs-comment,
|
||||||
|
.hljs-quote {
|
||||||
|
color: #7d8590 !important;
|
||||||
|
}
|
||||||
|
.hljs-built_in {
|
||||||
|
color: #ffa198 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ========== 附件和文件卡片深色样式 ========== */
|
/* ========== 附件和文件卡片深色样式 ========== */
|
||||||
@@ -1501,7 +1757,7 @@
|
|||||||
.el-sender{
|
.el-sender{
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.typer-content{
|
.typer-content{
|
||||||
color: #fff !important;
|
color: #fff !important;
|
||||||
}
|
}
|
||||||
@@ -1597,7 +1853,7 @@
|
|||||||
}
|
}
|
||||||
.session-sidebar{
|
.session-sidebar{
|
||||||
background: #04080b !important
|
background: #04080b !important
|
||||||
|
|
||||||
}
|
}
|
||||||
.session-sidebar .session-item:hover{
|
.session-sidebar .session-item:hover{
|
||||||
background: transparent !important;
|
background: transparent !important;
|
||||||
@@ -1753,7 +2009,7 @@
|
|||||||
@include dark-theme-div;
|
@include dark-theme-div;
|
||||||
}
|
}
|
||||||
.el-check-tag.el-check-tag--primary.is-checked{
|
.el-check-tag.el-check-tag--primary.is-checked{
|
||||||
color: #00ff88 !important;
|
color: #00ff88 !important;
|
||||||
}
|
}
|
||||||
.el-check-tag{
|
.el-check-tag{
|
||||||
@include dark-theme-div;
|
@include dark-theme-div;
|
||||||
|
|||||||
@@ -172,6 +172,15 @@ export function toClaudeFormat(messages: UnifiedMessage[]): { messages: ClaudeMe
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Claude API 要求第一条消息必须是 user 角色,不能以 assistant 开头
|
||||||
|
// 如果第一条是 assistant,在前面插入一个空的 user 消息
|
||||||
|
if (claudeMessages.length > 0 && claudeMessages[0].role !== 'user') {
|
||||||
|
claudeMessages.unshift({
|
||||||
|
role: 'user',
|
||||||
|
content: '',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return { messages: claudeMessages, system: systemPrompt };
|
return { messages: claudeMessages, system: systemPrompt };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user