优化智能助手展示页面,【重要优化】
This commit is contained in:
parent
83446c092c
commit
e05f5f9c6e
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "渠道应用开发部知识库",
|
"name": "渠道应用开发部知识库",
|
||||||
"version": "2.0.14",
|
"version": "2.0.15",
|
||||||
"description": "通过关键词快速搜索内部文档",
|
"description": "通过关键词快速搜索内部文档",
|
||||||
"permissions": ["storage"],
|
"permissions": ["storage"],
|
||||||
"host_permissions": [
|
"host_permissions": [
|
||||||
|
|||||||
@ -18,5 +18,6 @@
|
|||||||
| 2025.06.24 | V2.0.12 | Luke.Ye | 添加测试页面 |
|
| 2025.06.24 | V2.0.12 | Luke.Ye | 添加测试页面 |
|
||||||
| 2025.06.28 | V2.0.13 | Luke.Ye | 优化分页展示 |
|
| 2025.06.28 | V2.0.13 | Luke.Ye | 优化分页展示 |
|
||||||
| 2025.07.03 | V2.0.14 | Luke.Ye | test页面逻辑优化 |
|
| 2025.07.03 | V2.0.14 | Luke.Ye | test页面逻辑优化 |
|
||||||
|
| 2025.07.09 | V2.0.15 | Luke.Ye | 优化“智能助手”展示页面 |
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -333,6 +333,10 @@ async function getLLMToken(forceRefresh = false) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 放在全局(或函数外部,确保多次渲染只绑定一次即可)
|
||||||
|
let isUserAtBottom = true;
|
||||||
|
let scrollListenerInited = false;
|
||||||
|
|
||||||
async function fetchLLMAnswer(question, container, contentDiv) {
|
async function fetchLLMAnswer(question, container, contentDiv) {
|
||||||
if (!question || !question.trim()) return;
|
if (!question || !question.trim()) return;
|
||||||
|
|
||||||
@ -354,7 +358,7 @@ async function fetchLLMAnswer(question, container, contentDiv) {
|
|||||||
const userToken = auth.token;
|
const userToken = auth.token;
|
||||||
const url = config.apiConfig.llmChat.url;
|
const url = config.apiConfig.llmChat.url;
|
||||||
|
|
||||||
// ... 你的渲染用户输入的代码 ...
|
// ... 渲染用户输入 ...
|
||||||
const userItem = document.createElement("div");
|
const userItem = document.createElement("div");
|
||||||
userItem.className = "llm-msg-item llm-user";
|
userItem.className = "llm-msg-item llm-user";
|
||||||
userItem.innerHTML = `<span style="color:#2a63c8;font-weight:bold;">我:</span> ${question}`;
|
userItem.innerHTML = `<span style="color:#2a63c8;font-weight:bold;">我:</span> ${question}`;
|
||||||
@ -364,10 +368,19 @@ async function fetchLLMAnswer(question, container, contentDiv) {
|
|||||||
const msgBox = document.createElement("div");
|
const msgBox = document.createElement("div");
|
||||||
msgBox.className = "llm-msg-item llm-assistant";
|
msgBox.className = "llm-msg-item llm-assistant";
|
||||||
contentDiv.appendChild(msgBox);
|
contentDiv.appendChild(msgBox);
|
||||||
contentDiv.scrollTop = contentDiv.scrollHeight;
|
|
||||||
|
// 只绑定一次滚动监听,且在首次流式渲染时保证已绑定
|
||||||
|
const resultContent = document.getElementById("llmResultContent");
|
||||||
|
if (resultContent && !scrollListenerInited) {
|
||||||
|
resultContent.addEventListener("scroll", function() {
|
||||||
|
isUserAtBottom = resultContent.scrollTop + resultContent.clientHeight >= resultContent.scrollHeight - 20;
|
||||||
|
});
|
||||||
|
scrollListenerInited = true;
|
||||||
|
}
|
||||||
|
|
||||||
let collectedSources = [];
|
let collectedSources = [];
|
||||||
let jumpMap = {};
|
let jumpMap = {};
|
||||||
|
|
||||||
// LLM 问答接口流式处理
|
// LLM 问答接口流式处理
|
||||||
try {
|
try {
|
||||||
const body = { llmToken, question };
|
const body = { llmToken, question };
|
||||||
@ -436,7 +449,7 @@ async function fetchLLMAnswer(question, container, contentDiv) {
|
|||||||
answerStr += content;
|
answerStr += content;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 每次都要渲染(不管内容是否为空)
|
// 渲染
|
||||||
let html = "";
|
let html = "";
|
||||||
try {
|
try {
|
||||||
html = window.marked ? wrapHtmlWithCopyBtn(marked.parse(answerStr)) : answerStr.replace(/\n/g, "<br>");
|
html = window.marked ? wrapHtmlWithCopyBtn(marked.parse(answerStr)) : answerStr.replace(/\n/g, "<br>");
|
||||||
@ -450,7 +463,11 @@ async function fetchLLMAnswer(question, container, contentDiv) {
|
|||||||
|
|
||||||
bindAllCopyButtons(msgBox);
|
bindAllCopyButtons(msgBox);
|
||||||
insertCopyFullAnswerBtn(msgBox, answerStr);
|
insertCopyFullAnswerBtn(msgBox, answerStr);
|
||||||
contentDiv.scrollTop = contentDiv.scrollHeight;
|
|
||||||
|
// === 核心优化:只在用户停留底部时才自动滚到底 ===
|
||||||
|
if (resultContent && isUserAtBottom) {
|
||||||
|
resultContent.scrollTop = resultContent.scrollHeight;
|
||||||
|
}
|
||||||
|
|
||||||
// 收尾渲染引用
|
// 收尾渲染引用
|
||||||
if (chunk.close === true) {
|
if (chunk.close === true) {
|
||||||
|
|||||||
@ -159,7 +159,7 @@ body.fullscreen #tabContentAi.tab-content.active {
|
|||||||
|
|
||||||
.llm-md {
|
.llm-md {
|
||||||
font-size: 14.2px;
|
font-size: 14.2px;
|
||||||
line-height: 1.72;
|
line-height: 1.48;
|
||||||
color: #222d3b;
|
color: #222d3b;
|
||||||
background: #fcfcfe;
|
background: #fcfcfe;
|
||||||
border-radius: 7px;
|
border-radius: 7px;
|
||||||
@ -170,45 +170,81 @@ body.fullscreen #tabContentAi.tab-content.active {
|
|||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 段落、标题、块状元素间距 */
|
/* 块级元素 margin 清零,只靠外部统一间距 */
|
||||||
.llm-md p,
|
.llm-md p,
|
||||||
.llm-md ul, .llm-md ol, .llm-md pre, .llm-md blockquote, .llm-md table {
|
.llm-md ul,
|
||||||
margin-top: 0;
|
.llm-md ol,
|
||||||
margin-bottom: 0;
|
.llm-md pre,
|
||||||
}
|
.llm-md blockquote,
|
||||||
.llm-md h1, .llm-md h2, .llm-md h3, .llm-md h4, .llm-md h5, .llm-md h6 {
|
.llm-md table,
|
||||||
margin-top: 1.2em;
|
.llm-md h1,
|
||||||
margin-bottom: 0.6em;
|
.llm-md h2,
|
||||||
font-weight: bold;
|
.llm-md h3,
|
||||||
color: #2560de;
|
.llm-md h4,
|
||||||
line-height: 1.22;
|
.llm-md h5,
|
||||||
}
|
.llm-md h6 {
|
||||||
.llm-md h1 { font-size: 1.22em; border-bottom: 2px solid #e7eaf5; padding-bottom: 3px; }
|
margin: 0;
|
||||||
.llm-md h2 { font-size: 1.13em; border-bottom: 1px solid #eceff5; padding-bottom: 2px;}
|
|
||||||
.llm-md h3 { font-size: 1.07em; }
|
|
||||||
.llm-md h4, .llm-md h5, .llm-md h6 { font-size: 1em; }
|
|
||||||
|
|
||||||
.llm-md > * + * {
|
|
||||||
margin-top: 0.74em; /* 块元素之间舒适的间隔 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.llm-md ul, .llm-md ol {
|
|
||||||
padding-left: 1.45em;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
.llm-md li {
|
|
||||||
margin-bottom: 0.16em;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
line-height: 1.62;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 统一块间距 */
|
||||||
|
.llm-md > * + * {
|
||||||
|
margin-top: 0.12em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 特殊:列表或段落后直接跟标题时,间距更窄 */
|
||||||
|
.llm-md ul + h1,
|
||||||
|
.llm-md ul + h2,
|
||||||
|
.llm-md ul + h3,
|
||||||
|
.llm-md ul + h4,
|
||||||
|
.llm-md ul + h5,
|
||||||
|
.llm-md ul + h6,
|
||||||
|
.llm-md ol + h1,
|
||||||
|
.llm-md ol + h2,
|
||||||
|
.llm-md ol + h3,
|
||||||
|
.llm-md ol + h4,
|
||||||
|
.llm-md ol + h5,
|
||||||
|
.llm-md ol + h6,
|
||||||
|
.llm-md p + h1,
|
||||||
|
.llm-md p + h2,
|
||||||
|
.llm-md p + h3,
|
||||||
|
.llm-md p + h4,
|
||||||
|
.llm-md p + h5,
|
||||||
|
.llm-md p + h6 {
|
||||||
|
margin-top: 0.02em !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- 列表优化区 ---- */
|
||||||
|
.llm-md ul,
|
||||||
|
.llm-md ol {
|
||||||
|
padding-left: 1.18em;
|
||||||
|
margin-left: 0;
|
||||||
|
line-height: 1.17; /* 极紧凑,适合 IM/文档区块 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.llm-md li {
|
||||||
|
display: list-item;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
line-height: 1.17;
|
||||||
|
word-break: break-word;
|
||||||
|
/* 避免多余空间 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 如果 markdown 渲染成 <li><p>...</p></li>,强制清空 p 的 margin */
|
||||||
|
.llm-md li > p {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: inline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- 其他样式保持原样 ---- */
|
||||||
.llm-md blockquote {
|
.llm-md blockquote {
|
||||||
background: #f6f9fd;
|
background: #f6f9fd;
|
||||||
border-left: 4px solid #a4c0f0;
|
border-left: 4px solid #a4c0f0;
|
||||||
padding: 8px 17px;
|
padding: 7px 15px;
|
||||||
margin: 9px 0 11px 0;
|
|
||||||
color: #395fa9;
|
color: #395fa9;
|
||||||
font-size: 13.6px;
|
font-size: 13.5px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,9 +252,8 @@ body.fullscreen #tabContentAi.tab-content.active {
|
|||||||
background: #f5f7fa;
|
background: #f5f7fa;
|
||||||
color: #26324b;
|
color: #26324b;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
padding: 15px 19px 15px 17px;
|
padding: 12px 15px 12px 13px;
|
||||||
font-size: 13.5px;
|
font-size: 13.3px;
|
||||||
margin: 8px 0 11px 0;
|
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
box-shadow: 0 2px 8px #e0eaf422;
|
box-shadow: 0 2px 8px #e0eaf422;
|
||||||
position: relative;
|
position: relative;
|
||||||
@ -239,66 +274,24 @@ body.fullscreen #tabContentAi.tab-content.active {
|
|||||||
background: #f7f6f4;
|
background: #f7f6f4;
|
||||||
color: #a72543;
|
color: #a72543;
|
||||||
border-radius: 3.5px;
|
border-radius: 3.5px;
|
||||||
padding: 2.5px 6px;
|
padding: 2px 6px;
|
||||||
font-size: 92%;
|
font-size: 92%;
|
||||||
font-family: 'JetBrains Mono', 'Fira Mono', 'Consolas', 'monospace';
|
font-family: 'JetBrains Mono', 'Fira Mono', 'Consolas', 'monospace';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 复制按钮右上角美观悬浮 */
|
|
||||||
.llm-md .copy-btn {
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
right: 14px;
|
|
||||||
background: #eef1f9;
|
|
||||||
color: #3661b2;
|
|
||||||
border: 1px solid #dde4ef;
|
|
||||||
border-radius: 5px;
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 2px 13px 2px 13px;
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0.76;
|
|
||||||
z-index: 10;
|
|
||||||
transition: background 0.16s, opacity 0.16s;
|
|
||||||
box-shadow: 0 1px 3px #ccd4f522;
|
|
||||||
font-weight: 500;
|
|
||||||
height: 22px;
|
|
||||||
line-height: 1.5;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.llm-md .copy-btn:hover {
|
|
||||||
background: #e1eaff;
|
|
||||||
opacity: 1;
|
|
||||||
color: #184d99;
|
|
||||||
}
|
|
||||||
|
|
||||||
.llm-md pre:hover .copy-btn {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.llm-md table {
|
|
||||||
border-collapse: collapse;
|
|
||||||
margin: 12px 0;
|
|
||||||
width: 100%;
|
|
||||||
background: #fff;
|
|
||||||
box-shadow: 0 1px 5px #e3eaf5;
|
|
||||||
font-size: 13px;
|
|
||||||
}
|
|
||||||
.llm-md th, .llm-md td {
|
|
||||||
border: 1px solid #e5e9f2;
|
|
||||||
padding: 8px 13px;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.llm-md th {
|
|
||||||
background: #f5f7fc;
|
|
||||||
color: #2c4e9c;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.llm-md hr {
|
.llm-md hr {
|
||||||
border: none;
|
border: none;
|
||||||
border-top: 1.5px dashed #d1d7e6;
|
border-top: 1px dashed #d1d7e6;
|
||||||
margin: 18px 0 15px 0;
|
margin: 4px 0 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.llm-md hr + h1,
|
||||||
|
.llm-md hr + h2,
|
||||||
|
.llm-md hr + h3,
|
||||||
|
.llm-md hr + h4,
|
||||||
|
.llm-md hr + h5,
|
||||||
|
.llm-md hr + h6 {
|
||||||
|
margin-top: 0.03em !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.llm-md a {
|
.llm-md a {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user