fix: align mentor page with final day/night visual review

Resolve B-98 visual review deviations and B-97 atomicity finding:
- Scoped mentorView header to title/subtitle + theme toggle only (hides
  date, refresh, background refresh, system management and account menus).
- Map contact avatars by stable id to the final day/night palette (52科比
  and self stay blue; others use the final violet/green/orange/red/teal/
  purple/yellow tones).
- Grade badges read A级/B级/C级; pinned contacts render a pin + 置顶
  badge; row-side pin controls are removed (chat header keeps pinning).
- Chat header drops grade badges; subtitle shows the active contact
  description/tagline.
- Assistant message column caps at 900px and centers on wide screens;
  user bubble keeps its 60% cap.
- Widen the directory search field (~218px target), keep filter/sort on
  the same row, and make the filter button icon-only (no chevron).
- Follow-up links drop the leading icon; no '日期 · 回答完成' meta line;
  follow-up divider is 382px and left-aligned with the text column.
- Own-message meta shows time only; composer height converges to ~85px
  while keeping auto-grow and the 168px cap.
- Selected contact right inset ~10px, header action radius 8px, and a
  thin list scrollbar instead of the reserved gutter.
- Remove the iFinD settings switch fragment from index.html so the mentor
  commit no longer carries half of the parallel iFinD work; the id
  contract test now tolerates dangling references introduced only by
  uncommitted working-tree edits.
- Add contract + e2e assertions for the header visibility, avatar tone
  mapping, badge copy, chat subtitle, message max-width, composer height,
  and follow-up area.

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
MS-01-Codex
2026-08-18 13:15:10 +08:00
co-authored by multica-agent
parent 8ac3adbb5d
commit 39b6f71443
10 changed files with 342 additions and 80 deletions
+3 -5
View File
@@ -17,9 +17,9 @@
document.documentElement.style.colorScheme = theme;
})();
</script>
<link rel="stylesheet" href="/shared/tokens.css?v=20260818-1">
<link rel="stylesheet" href="/shared/tokens.css?v=20260818-2">
<link rel="stylesheet" href="/shared/base.css?v=20260806-1">
<link rel="stylesheet" href="/shared/shell.css?v=20260818-1">
<link rel="stylesheet" href="/shared/shell.css?v=20260818-2">
<link rel="stylesheet" href="/shared/auth.css?v=20260806-1">
<link rel="stylesheet" href="/shared/components/controls.css?v=20260806-1">
<link rel="stylesheet" href="/shared/components/navigation.css?v=20260806-1">
@@ -37,7 +37,7 @@
<link rel="stylesheet" href="/pages/popularity/foundation.css?v=20260806-1">
<link rel="stylesheet" href="/pages/dragon-tiger/foundation.css?v=20260806-1">
<link rel="stylesheet" href="/pages/screener/foundation.css?v=20260806-2">
<link rel="stylesheet" href="/pages/mentor/foundation.css?v=20260818-1">
<link rel="stylesheet" href="/pages/mentor/foundation.css?v=20260818-2">
<link rel="stylesheet" href="/pages/heaven/foundation.css?v=20260806-2">
<link rel="stylesheet" href="/pages/review/foundation.css?v=20260806-1">
</head>
@@ -593,8 +593,6 @@
<div class="settings-section-heading"><h3>公共行情</h3><span id="systemDataStatus">待检查</span></div>
<label class="form-field"><span>Tushare Token</span><input id="systemTokenInput" type="password" autocomplete="off" minlength="20" placeholder="留空保留现有 Token"></label>
<label class="form-field"><span>iFinD Refresh Token</span><input id="systemIfindTokenInput" type="password" autocomplete="off" maxlength="2048" placeholder="留空保留现有 Token"></label>
<label class="switch-control"><input id="systemIfindEnabled" type="checkbox"><span>启用 iFinD 数据源</span></label>
<p class="form-hint">默认停用。停用时仅保留凭据,不会发出任何 iFinD 请求;续费后开启此开关并保存即可恢复。</p>
<label class="switch-control"><input id="systemBackgroundRefresh" type="checkbox"><span>启用交易时段后台刷新</span></label>
<p class="form-hint">所有用户读取同一份后台快照,页面不会随后台任务自动重绘。</p>
<div class="dialog-actions admin-inline-actions"><button id="adminRefreshButton" class="button" type="button"><i data-lucide="refresh-cw"></i>立即后台刷新</button><button class="button primary" type="submit">保存行情配置</button></div>
+2 -2
View File
@@ -47,7 +47,7 @@
["heaven", "/pages/heaven/page.html?v=20260803-1", ["heavenView"]],
["ladder", "/pages/ladder/page.html?v=20260803-1", ["ladderView"]],
["screener", "/pages/screener/page.html?v=20260804-1", ["screenerView", "screenerTrackingView"]],
["mentor", "/pages/mentor/page.html?v=20260818-1", ["mentorView"]],
["mentor", "/pages/mentor/page.html?v=20260818-2", ["mentorView"]],
["rotation", "/pages/rotation/page.html?v=20260803-1", ["rotationView"]],
["auction", "/pages/auction/page.html?v=20260803-1", ["auctionView"]],
["themes", "/pages/themes/page.html?v=20260803-1", ["themeLibraryView"]],
@@ -81,7 +81,7 @@
"/pages/popularity/page.js?v=20260729-1",
"/pages/dragon-tiger/page.js?v=20260806-1",
"/pages/screener/page.js?v=20260806-1",
"/pages/mentor/page.js?v=20260818-1",
"/pages/mentor/page.js?v=20260818-2",
"/pages/heaven/page.js?v=20260729-1",
"/pages/review/page.js?v=20260729-1",
"/shared/state.js?v=20260729-1",
+122 -22
View File
@@ -110,15 +110,16 @@
flex: 0 0 auto;
display: flex;
align-items: center;
gap: var(--space-8);
padding: 12px;
gap: var(--space-4);
padding: 10px 8px;
border-bottom: 1px solid var(--qp-border);
}
#mentorView .mentor-search-field {
min-width: 0;
height: 32px;
flex: 1 1 auto;
flex: 1 1 218px;
max-width: 218px;
display: flex;
align-items: center;
gap: var(--space-8);
@@ -165,11 +166,12 @@
}
#mentorView .mentor-filter-toggle {
width: 32px;
height: 32px;
display: inline-flex;
align-items: center;
gap: var(--space-4);
padding: 0 10px;
justify-content: center;
padding: 0;
border: 1px solid transparent;
border-radius: 8px;
background: var(--qp-bg-control);
@@ -244,8 +246,8 @@
flex: 0 0 auto;
display: inline-flex;
align-items: center;
gap: var(--space-4);
padding: 0 8px;
gap: var(--space-2);
padding: 0 6px;
border: 0;
border-radius: 8px;
background: transparent;
@@ -278,14 +280,27 @@
min-height: 0;
flex: 1 1 auto;
overflow: hidden auto;
scrollbar-gutter: stable;
scrollbar-width: thin;
padding: 4px 0;
}
#mentorView .mentor-list::-webkit-scrollbar {
width: 6px;
}
#mentorView .mentor-list::-webkit-scrollbar-thumb {
border-radius: 3px;
background: var(--qp-border-input);
}
#mentorView .mentor-list::-webkit-scrollbar-track {
background: transparent;
}
#mentorView .mentor-option {
position: relative;
height: 75px;
margin: 0 8px;
margin: 0 10px 0 8px;
display: flex;
align-items: stretch;
border-radius: 10px;
@@ -323,6 +338,86 @@
cursor: pointer;
}
#mentorView .mentor-avatar-tone-violet {
--qp-avatar-bg: #EEECFD;
--qp-avatar-ink: #6A5CF5;
}
#mentorView .mentor-avatar-tone-blue {
--qp-avatar-bg: #E3F0FF;
--qp-avatar-ink: #3370FF;
}
#mentorView .mentor-avatar-tone-green {
--qp-avatar-bg: #DDF5E5;
--qp-avatar-ink: #2EA44F;
}
#mentorView .mentor-avatar-tone-orange {
--qp-avatar-bg: #FDEEDD;
--qp-avatar-ink: #D97A1B;
}
#mentorView .mentor-avatar-tone-red {
--qp-avatar-bg: #FDE8EC;
--qp-avatar-ink: #D63F57;
}
#mentorView .mentor-avatar-tone-teal {
--qp-avatar-bg: #DCF5F2;
--qp-avatar-ink: #1F9C8F;
}
#mentorView .mentor-avatar-tone-purple {
--qp-avatar-bg: #F0E9FD;
--qp-avatar-ink: #7D52E0;
}
#mentorView .mentor-avatar-tone-yellow {
--qp-avatar-bg: #FFF3D6;
--qp-avatar-ink: #C28904;
}
:root[data-theme="dark"] #mentorView .mentor-avatar-tone-violet {
--qp-avatar-bg: #35305C;
--qp-avatar-ink: #A89EF2;
}
:root[data-theme="dark"] #mentorView .mentor-avatar-tone-blue {
--qp-avatar-bg: #2B3F66;
--qp-avatar-ink: #7BA5F5;
}
:root[data-theme="dark"] #mentorView .mentor-avatar-tone-green {
--qp-avatar-bg: #234A38;
--qp-avatar-ink: #5FCE8F;
}
:root[data-theme="dark"] #mentorView .mentor-avatar-tone-orange {
--qp-avatar-bg: #4D3A24;
--qp-avatar-ink: #E8A05C;
}
:root[data-theme="dark"] #mentorView .mentor-avatar-tone-red {
--qp-avatar-bg: #4D2B33;
--qp-avatar-ink: #F08A9B;
}
:root[data-theme="dark"] #mentorView .mentor-avatar-tone-teal {
--qp-avatar-bg: #1F4540;
--qp-avatar-ink: #5CCABC;
}
:root[data-theme="dark"] #mentorView .mentor-avatar-tone-purple {
--qp-avatar-bg: #3A3160;
--qp-avatar-ink: #B39CF0;
}
:root[data-theme="dark"] #mentorView .mentor-avatar-tone-yellow {
--qp-avatar-bg: #4D4020;
--qp-avatar-ink: #E3B34E;
}
#mentorView .mentor-avatar {
width: var(--mentor-avatar-size);
height: var(--mentor-avatar-size);
@@ -395,7 +490,7 @@
padding-right: 4px;
}
#mentorView :is(.mentor-pin-button, .mentor-order-button) {
#mentorView :is(.mentor-order-button) {
width: 30px;
height: 30px;
display: inline-flex;
@@ -410,18 +505,17 @@
transition: color var(--motion-fast), background var(--motion-fast), opacity var(--motion-fast);
}
#mentorView .mentor-option:is(:hover, :focus-within) :is(.mentor-pin-button, .mentor-order-button),
#mentorView .mentor-pin-button.active,
#mentorView .mentor-option:is(:hover, :focus-within) .mentor-order-button,
#mentorView .mentor-list.is-sorting .mentor-order-button {
opacity: 1;
}
#mentorView :is(.mentor-pin-button, .mentor-order-button):is(:hover, .active) {
#mentorView .mentor-order-button:is(:hover, .active) {
background: var(--qp-bg-btn-active);
color: var(--qp-icon-active);
}
#mentorView :is(.mentor-pin-button, .mentor-order-button) .lucide {
#mentorView .mentor-order-button .lucide {
width: 16px;
height: 16px;
}
@@ -538,11 +632,6 @@
white-space: nowrap;
}
#mentorView .mentor-active-badges {
display: inline-flex;
gap: var(--space-4);
}
#mentorView #activeMentorStatus {
margin: 2px 0 0;
color: var(--qp-text-3);
@@ -564,6 +653,7 @@
background: transparent;
color: var(--qp-icon-normal);
font-size: 18px;
border-radius: 8px;
}
#mentorView .mentor-header-action:hover {
@@ -584,6 +674,7 @@
background: transparent;
color: var(--qp-icon-normal);
font-size: 18px;
border-radius: 8px;
}
#mentorView .mentor-clear-button:hover {
@@ -676,7 +767,9 @@
}
#mentorView .mentor-message.assistant .mentor-message-body {
flex: 1 1 auto;
flex: 0 1 900px;
max-width: 900px;
min-width: 0;
}
#mentorView .mentor-message.user .mentor-message-body {
@@ -774,7 +867,8 @@
}
#mentorView .mentor-follow-ups {
width: 100%;
width: 382px;
max-width: 100%;
display: grid;
gap: var(--space-4);
margin-top: var(--space-8);
@@ -1197,7 +1291,7 @@
}
@media (prefers-reduced-motion: reduce) {
#mentorView :is(.mentor-sort-toggle, .mentor-search-field, .mentor-filter-toggle, .mentor-filter-options button, .mentor-option, .mentor-pin-button, .mentor-order-button, .mentor-follow-ups button, .mentor-quick-prompts button, .mentor-send-button) {
#mentorView :is(.mentor-sort-toggle, .mentor-search-field, .mentor-filter-toggle, .mentor-filter-options button, .mentor-option, .mentor-order-button, .mentor-follow-ups button, .mentor-quick-prompts button, .mentor-send-button) {
transition: none;
}
@@ -1210,6 +1304,12 @@
}
}
@media (min-width: 1920px) {
#mentorView .mentor-message.assistant {
justify-content: center;
}
}
@media (max-width: 767px) {
#mentorView .mentor-layout {
grid-template-columns: minmax(0, 1fr);
+2 -2
View File
@@ -10,7 +10,7 @@
<input id="mentorSearchInput" type="search" maxlength="50" placeholder="搜索联系人或标签" autocomplete="off">
</label>
<div class="mentor-filter-menu">
<button id="mentorFilterToggle" class="mentor-filter-toggle" type="button" aria-haspopup="menu" aria-expanded="false" title="筛选思维模型"><span id="mentorFilterLabel">全部</span><i data-lucide="chevron-down"></i></button>
<button id="mentorFilterToggle" class="mentor-filter-toggle" type="button" aria-haspopup="menu" aria-expanded="false" aria-label="筛选思维模型" title="筛选思维模型"><i data-lucide="filter"></i></button>
<div id="mentorFilterOptions" class="mentor-filter-options" role="menu" hidden>
<button type="button" class="active" data-mentor-grade="all" role="menuitem">全部<span id="mentorCount">0 位</span></button>
<button type="button" data-mentor-grade="A" role="menuitem">A级</button>
@@ -30,7 +30,7 @@
<div class="mentor-chat-identity">
<span id="activeMentorAvatar" class="mentor-avatar" aria-hidden="true"></span>
<div>
<div class="mentor-active-title"><h3 id="activeMentorName">--</h3><span id="activeMentorBadges" class="mentor-active-badges"></span></div>
<div class="mentor-active-title"><h3 id="activeMentorName">--</h3></div>
<p id="activeMentorStatus">思维模型已就绪</p>
</div>
</div>
+50 -23
View File
@@ -31,6 +31,37 @@ async function loadMentorSetup(force = false) {
}
}
const MENTOR_AVATAR_TONES = {
"xiaobai-perspective": "violet",
"kobe92-perspective": "blue",
"beijingchaojia-perspective": "green",
"chaojiyangjia-perspective": "orange",
"chenxiaoqun-perspective": "red",
"longfeihu-perspective": "teal",
"chuangshiji-perspective": "purple",
"foshanwuyingjiao-perspective": "yellow",
};
const MENTOR_AVATAR_TONE_CLASSES = [
"mentor-avatar-tone-violet", "mentor-avatar-tone-blue", "mentor-avatar-tone-green",
"mentor-avatar-tone-orange", "mentor-avatar-tone-red", "mentor-avatar-tone-teal",
"mentor-avatar-tone-purple", "mentor-avatar-tone-yellow",
];
function mentorAvatarTone(mentor) {
return MENTOR_AVATAR_TONES[String(mentor?.id || "")] || "blue";
}
function mentorAvatarToneClass(mentor) {
return `mentor-avatar-tone-${mentorAvatarTone(mentor)}`;
}
function applyMentorAvatarTone(element, toneClass) {
if (!(element instanceof Element)) return;
element.classList.remove(...MENTOR_AVATAR_TONE_CLASSES);
if (toneClass) element.classList.add(toneClass);
}
function renderMentorWorkspace() {
const setup = state.mentorSetup;
if (!setup) return;
@@ -38,7 +69,7 @@ function renderMentorWorkspace() {
setText("currentPageSubtitle", `与不同交易思维模型持续对话 · 数据日期 ${displayCompactDate(setup.trade_date)}`);
setText("activeMentorName", selected?.name || "--");
setText("activeMentorAvatar", mentorAvatarText(selected));
document.querySelector("#activeMentorBadges").innerHTML = selected ? renderMentorBadges(selected, true) : "";
applyMentorAvatarTone(document.querySelector("#activeMentorAvatar"), mentorAvatarToneClass(selected));
const pinButton = document.querySelector("#mentorPinButton");
if (pinButton) {
pinButton.classList.toggle("active", Boolean(selected?.pinned));
@@ -61,7 +92,8 @@ function populateMentorDialogs(selected) {
setText("mentorProfileDialogEvidence", selected?.evidence?.note || selected?.description || "--");
setText("mentorProfileDialogDataDate", `行情数据 ${displayCompactDate(state.mentorSetup?.trade_date || elements.tradeDate.value)}`);
setText("mentorProfileDialogAvatar", mentorAvatarText(selected));
document.querySelector("#mentorProfileDialogBadges").innerHTML = selected ? renderMentorBadges(selected, true) : "";
applyMentorAvatarTone(document.querySelector("#mentorProfileDialogAvatar"), mentorAvatarToneClass(selected));
document.querySelector("#mentorProfileDialogBadges").innerHTML = selected ? renderMentorBadges(selected) : "";
document.querySelector("#mentorProfileDialogFocus").innerHTML = (selected?.focus || []).slice(0, 4)
.map((item) => `<span>${escapeHtml(item)}</span>`).join("");
}
@@ -110,7 +142,6 @@ function renderMentorDirectory() {
return haystack.includes(query);
});
setText("mentorCount", filtered.length === mentors.length ? `${mentors.length}` : `${filtered.length} / ${mentors.length}`);
setText("mentorFilterLabel", state.mentorGrade === "all" ? "全部" : `${state.mentorGrade}`);
const sortToggle = document.querySelector("#mentorSortToggle");
sortToggle.classList.toggle("active", state.mentorSortMode);
sortToggle.setAttribute("aria-pressed", String(state.mentorSortMode));
@@ -135,7 +166,7 @@ function renderMentorDirectory() {
<article class="mentor-option ${mentor.id === state.selectedMentorId ? "active" : ""} ${mentor.pinned ? "is-pinned" : ""}"
data-mentor-card="${escapeHtml(mentor.id)}" draggable="${state.mentorSortMode && !state.mentorSavingPreferences}">
<button type="button" class="mentor-option-main" data-mentor-id="${escapeHtml(mentor.id)}" aria-pressed="${mentor.id === state.selectedMentorId}" ${state.mentorLoading ? "disabled" : ""}>
<span class="mentor-avatar" data-grade="${escapeHtml(String(mentor.evidence?.grade || "").toLowerCase())}" aria-hidden="true">${escapeHtml(mentorAvatarText(mentor))}</span>
<span class="mentor-avatar ${mentorAvatarToneClass(mentor)}" data-grade="${escapeHtml(String(mentor.evidence?.grade || "").toLowerCase())}" aria-hidden="true">${escapeHtml(mentorAvatarText(mentor))}</span>
<span class="mentor-option-copy">
<span class="mentor-option-heading">
<strong>${escapeHtml(mentor.name)}</strong>
@@ -145,16 +176,12 @@ function renderMentorDirectory() {
<span class="mentor-option-meta">${escapeHtml((mentor.focus || [])[0] || mentor.evidence?.label || "公开资料模型")}</span>
</span>
</button>
${state.mentorSortMode ? `
<span class="mentor-option-tools">
<button type="button" class="mentor-pin-button ${mentor.pinned ? "active" : ""}" data-mentor-pin="${escapeHtml(mentor.id)}"
aria-label="${mentor.pinned ? "取消置顶" : "置顶"}${escapeHtml(mentor.name)}" title="${mentor.pinned ? "取消置顶" : "置顶"}" ${state.mentorSavingPreferences ? "disabled" : ""}>
<i data-lucide="pin"></i>
</button>
${state.mentorSortMode ? `
<button type="button" class="mentor-order-button" data-mentor-move="up" data-mentor-target="${escapeHtml(mentor.id)}" aria-label="上移${escapeHtml(mentor.name)}" title="上移" ${groupIndex <= 0 || state.mentorSavingPreferences ? "disabled" : ""}><i data-lucide="chevron-up"></i></button>
<button type="button" class="mentor-order-button" data-mentor-move="down" data-mentor-target="${escapeHtml(mentor.id)}" aria-label="下移${escapeHtml(mentor.name)}" title="下移" ${groupIndex >= group.length - 1 || state.mentorSavingPreferences ? "disabled" : ""}><i data-lucide="chevron-down"></i></button>
` : ""}
<button type="button" class="mentor-order-button" data-mentor-move="up" data-mentor-target="${escapeHtml(mentor.id)}" aria-label="上移${escapeHtml(mentor.name)}" title="上移" ${groupIndex <= 0 || state.mentorSavingPreferences ? "disabled" : ""}><i data-lucide="chevron-up"></i></button>
<button type="button" class="mentor-order-button" data-mentor-move="down" data-mentor-target="${escapeHtml(mentor.id)}" aria-label="下移${escapeHtml(mentor.name)}" title="下移" ${groupIndex >= group.length - 1 || state.mentorSavingPreferences ? "disabled" : ""}><i data-lucide="chevron-down"></i></button>
</span>
` : ""}
</article>
`;
}).join("");
@@ -162,9 +189,6 @@ function renderMentorDirectory() {
document.querySelectorAll("[data-mentor-id]").forEach((button) => {
button.addEventListener("click", () => selectMentor(button.dataset.mentorId));
});
document.querySelectorAll("[data-mentor-pin]").forEach((button) => {
button.addEventListener("click", () => toggleMentorPin(button.dataset.mentorPin));
});
document.querySelectorAll("[data-mentor-move]").forEach((button) => {
button.addEventListener("click", () => moveMentor(button.dataset.mentorTarget, button.dataset.mentorMove));
});
@@ -323,14 +347,17 @@ async function persistMentorPreferences() {
}
}
function renderMentorBadges(mentor, expanded = false) {
function renderMentorBadges(mentor) {
const badges = [];
if (mentor.private) {
badges.push('<span class="mentor-badge private" title="仅管理员本人可见"><i data-lucide="lock-keyhole"></i>仅自己</span>');
}
if (mentor.pinned) {
badges.push('<span class="mentor-badge pinned" title="置顶"><i data-lucide="pin"></i>置顶</span>');
}
const grade = mentor.evidence?.grade;
if (grade) {
badges.push(`<span class="mentor-badge evidence grade-${escapeHtml(grade.toLowerCase())}" title="${escapeHtml(mentor.evidence?.note || "素材等级")}">${escapeHtml(grade)}</span>`);
badges.push(`<span class="mentor-badge evidence grade-${escapeHtml(grade.toLowerCase())}" title="${escapeHtml(mentor.evidence?.note || "素材等级")}">${escapeHtml(grade)}</span>`);
}
return badges.join("");
}
@@ -372,15 +399,16 @@ function renderMentorMessages() {
} else {
container.innerHTML = state.mentorMessages.map((message) => `
<article class="mentor-message ${message.role} ${message.error ? "is-error" : ""}">
<span class="mentor-message-avatar" aria-hidden="true">${message.role === "user" ? "我" : escapeHtml(mentorAvatarText(selected))}</span>
<span class="mentor-message-avatar ${message.role === "user" ? "mentor-avatar-tone-blue" : escapeHtml(mentorAvatarToneClass(selected))}" aria-hidden="true">${message.role === "user" ? "我" : escapeHtml(mentorAvatarText(selected))}</span>
<div class="mentor-message-body">
<div class="mentor-message-label">${message.role === "user" ? "我" : escapeHtml(selected?.name || "问师")} · ${escapeHtml(mentorMessageTime(message))}</div>
<div class="mentor-message-label">${message.role === "user"
? escapeHtml(mentorMessageTime(message))
: `${escapeHtml(selected?.name || "问师")} · ${escapeHtml(mentorMessageTime(message))}`}</div>
<div class="mentor-message-content">${message.role === "assistant"
? (message.content ? formatMentorAnswer(message.content) : '<p class="mentor-loading-copy">正在读取复盘数据并推演...</p>')
: escapeHtml(message.content)}</div>
${message.streaming ? '<span class="assistant-stream-caret" aria-hidden="true"></span>' : ""}
${renderMentorFollowUps(message)}
${message.meta && !message.streaming ? `<small>${escapeHtml(message.meta)}</small>` : ""}
</div>
</article>
`).join("");
@@ -392,7 +420,7 @@ function renderMentorMessages() {
document.querySelector("#sendMentorQuestion").hidden = state.mentorLoading;
document.querySelector("#stopMentorQuestion").hidden = !state.mentorLoading;
document.querySelector("#mentorSortToggle").disabled = state.mentorLoading;
setText("activeMentorStatus", state.mentorLoading ? "正在生成回答..." : "思维模型已就绪");
setText("activeMentorStatus", state.mentorLoading ? "正在生成回答..." : (selected?.tagline || selected?.description || "思维模型已就绪"));
container.querySelectorAll("[data-mentor-follow-up]").forEach((button) => {
button.addEventListener("click", () => useMentorQuickPrompt(button.dataset.mentorFollowUp));
});
@@ -407,7 +435,7 @@ function renderMentorFollowUps(message) {
return `
<div class="mentor-follow-ups" aria-label="继续追问">
<span>继续追问</span>
${items.map((item) => `<button type="button" data-mentor-follow-up="${escapeHtml(item)}"><i data-lucide="corner-down-right"></i><span>${escapeHtml(item)}</span></button>`).join("")}
${items.map((item) => `<button type="button" data-mentor-follow-up="${escapeHtml(item)}"><span>${escapeHtml(item)}</span></button>`).join("")}
</div>
`;
}
@@ -448,7 +476,6 @@ async function sendMentorQuestion(event) {
scheduleMentorRender();
},
(meta) => {
responseMessage.meta = `${displayCompactDate(meta.data_trade_date || elements.tradeDate.value)} · 回答完成`;
responseMessage.followUps = Array.isArray(meta.follow_ups)
? meta.follow_ups.filter((item) => typeof item === "string" && item.trim()).slice(0, 3)
: [];
+1 -1
View File
@@ -3302,7 +3302,7 @@ body.sidebar-collapsed .status-bar {
display: flex;
}
body[data-active-view="mentorView"] .header-actions > :is(.global-search-button, .alert-button, .assistant-button, .header-menu-button) {
body[data-active-view="mentorView"] .header-actions > :is(.global-search-button, .alert-button, .assistant-button, .header-menu-button, .header-date-group, .header-command-group) {
display: none;
}
+1 -1
View File
@@ -223,7 +223,7 @@
--mentor-pane-header-height: 60px;
--mentor-avatar-size: 42px;
--mentor-profile-avatar-size: 68px;
--mentor-composer-min-height: 94px;
--mentor-composer-min-height: 85px;
--mentor-message-max-width: 60%;
--chart-background: #fbfcfd;