refactor: 重构消息区域模块化架构

- 将 messageArea.ts 拆分为多个独立模块
   - 新增 messageRenderer.ts:消息渲染逻辑
   - 新增 messageStyles.ts:样式定义
   - 新增 questionHandler.ts:问题处理
   - 新增 segmentRenderer.ts:分段渲染
   - 新增 textFormatter.ts:文本格式化
   - 新增 toolHelpers.ts:工具辅助函数
This commit is contained in:
Roe-xin
2026-03-12 15:46:18 +08:00
parent 2a280aaa93
commit c138406217
7 changed files with 1536 additions and 1737 deletions

View File

@ -0,0 +1,118 @@
/**
* 问题处理脚本模块
* 功能:用户问题交互逻辑
* 依赖textFormatter
* 使用场景webview 中的问题回答处理
*/
export function getQuestionHandlerScript(): string {
return `
const answeredQuestions = new Map();
function handleQuestionAnswer(askId, answer, questionDiv) {
console.log('[WebView] 用户选择答案:', askId, answer);
questionDiv.classList.add('answered');
const options = questionDiv.querySelectorAll('.question-option');
options.forEach(opt => {
if (opt.textContent === answer) {
opt.classList.add('selected');
}
});
vscode.postMessage({
command: 'submitAnswer',
askId: askId,
selected: [answer],
customInput: answer
});
}
function handleQuestionAnswerInSegment(askId, answer, segmentDiv) {
console.log('[WebView] 段落中用户选择答案:', askId, answer);
answeredQuestions.set(askId, answer);
segmentDiv.classList.add('answered');
const options = segmentDiv.querySelectorAll('.question-option');
options.forEach(opt => {
if (opt.getAttribute('data-option') === answer) {
opt.classList.add('selected');
}
});
const customContainer = segmentDiv.querySelector('.custom-input-container');
if (customContainer) {
customContainer.style.display = 'none';
}
vscode.postMessage({
command: 'submitAnswer',
askId: askId,
selected: [answer],
customInput: answer
});
}
function handleMultiQuestionAnswer(askId, answers, segmentDiv) {
console.log('[WebView] 多问题答案提交:', askId, answers);
answeredQuestions.set(askId, answers);
segmentDiv.classList.add('answered');
const inputs = segmentDiv.querySelectorAll('input');
inputs.forEach(input => {
input.disabled = true;
if (input.checked) {
const label = input.closest('.question-option');
if (label) {
label.classList.add('selected');
}
}
});
const submitBtn = segmentDiv.querySelector('.custom-submit');
if (submitBtn) {
submitBtn.style.display = 'none';
}
vscode.postMessage({
command: 'submitAnswer',
askId: askId,
answers: answers
});
}
function showQuestion(askId, question, options) {
console.log('[WebView] showQuestion 被调用:', askId, question, options);
const div = document.createElement('div');
div.className = 'message bot-message question-message';
div.setAttribute('data-ask-id', askId);
const questionText = document.createElement('div');
questionText.className = 'question-text';
questionText.textContent = question;
div.appendChild(questionText);
const optionsContainer = document.createElement('div');
optionsContainer.className = 'question-options';
options.forEach((option, index) => {
const optionBtn = document.createElement('button');
optionBtn.className = 'question-option';
optionBtn.textContent = option;
optionBtn.onclick = () => handleQuestionAnswer(askId, option, div);
optionsContainer.appendChild(optionBtn);
});
div.appendChild(optionsContainer);
const customContainer = document.createElement('div');
customContainer.className = 'custom-input-container';
const customInput = document.createElement('input');
customInput.type = 'text';
customInput.className = 'custom-input';
customInput.placeholder = '输入其他答案...';
const customSubmit = document.createElement('button');
customSubmit.className = 'custom-submit';
customSubmit.textContent = '提交';
customSubmit.onclick = () => {
const customValue = customInput.value.trim();
if (customValue) {
handleQuestionAnswer(askId, customValue, div);
}
};
customContainer.appendChild(customInput);
customContainer.appendChild(customSubmit);
div.appendChild(customContainer);
messagesEl.appendChild(div);
smartScrollToBottom();
checkHeaderVisibility();
}
`;
}