增強回饋文本生成,新增圖片的 Base64 預覽信息及兼容性說明,並將 alert 替換為通知功能以改善用戶體驗。

This commit is contained in:
Minidoracat 2025-05-31 02:16:09 +08:00
parent b0766f08ed
commit c02961d234
2 changed files with 81 additions and 10 deletions

View File

@ -186,7 +186,39 @@ def create_feedback_text(feedback_data: dict) -> str:
size_mb = size / (1024 * 1024) size_mb = size / (1024 * 1024)
size_str = f"{size_mb:.1f} MB" size_str = f"{size_mb:.1f} MB"
text_parts.append(f" {i}. {name} ({size_str})") img_info = f" {i}. {name} ({size_str})"
# 為提高兼容性,添加 base64 預覽信息
if img.get("data"):
try:
if isinstance(img["data"], bytes):
img_base64 = base64.b64encode(img["data"]).decode('utf-8')
elif isinstance(img["data"], str):
img_base64 = img["data"]
else:
img_base64 = None
if img_base64:
# 只顯示前50個字符的預覽
preview = img_base64[:50] + "..." if len(img_base64) > 50 else img_base64
img_info += f"\n Base64 預覽: {preview}"
img_info += f"\n 完整 Base64 長度: {len(img_base64)} 字符"
# 如果 AI 助手不支援 MCP 圖片,可以提供完整 base64
debug_log(f"圖片 {i} Base64 已準備,長度: {len(img_base64)}")
# 可選:根據環境變數決定是否包含完整 base64
include_full_base64 = os.getenv("INCLUDE_BASE64_DETAIL", "").lower() in ("true", "1", "yes", "on")
if include_full_base64:
img_info += f"\n 完整 Base64: data:image/png;base64,{img_base64}"
except Exception as e:
debug_log(f"圖片 {i} Base64 處理失敗: {e}")
text_parts.append(img_info)
# 添加兼容性說明
text_parts.append("\n💡 注意:如果 AI 助手無法顯示圖片,圖片數據已包含在上述 Base64 信息中。")
return "\n\n".join(text_parts) if text_parts else "用戶未提供任何回饋內容。" return "\n\n".join(text_parts) if text_parts else "用戶未提供任何回饋內容。"

View File

@ -628,22 +628,22 @@
} }
} }
} }
alert('剪貼板中沒有圖片!'); showNotification('剪貼板中沒有圖片!');
} catch (error) { } catch (error) {
console.error('剪貼板讀取失敗:', error); console.error('剪貼板讀取失敗:', error);
alert('無法從剪貼板讀取圖片'); showNotification('無法從剪貼板讀取圖片');
} }
} }
function processFiles(files) { function processFiles(files) {
for (const file of files) { for (const file of files) {
if (!file.type.startsWith('image/')) { if (!file.type.startsWith('image/')) {
alert(`檔案 ${file.name} 不是圖片格式!`); showNotification(`檔案 ${file.name} 不是圖片格式!`, 'warning');
continue; continue;
} }
if (file.size > 1024 * 1024) { // 1MB 限制 if (file.size > 1024 * 1024) { // 1MB 限制
alert(`圖片 ${file.name} 大小超過 1MB 限制!`); showNotification(`圖片 ${file.name} 大小超過 1MB 限制!`, 'warning');
continue; continue;
} }
@ -757,7 +757,7 @@
if (!command) return; if (!command) return;
if (commandRunning) { if (commandRunning) {
alert('已有命令在執行中,請等待完成或停止當前命令'); showNotification('已有命令在執行中,請等待完成或停止當前命令', 'warning');
return; return;
} }
@ -785,24 +785,63 @@
const feedback = document.getElementById('feedbackText').value.trim(); const feedback = document.getElementById('feedbackText').value.trim();
if (!feedback && images.length === 0) { if (!feedback && images.length === 0) {
alert('請輸入回饋內容或上傳圖片!'); showNotification('請輸入回饋內容或上傳圖片!', 'warning');
return; return;
} }
if (ws && ws.readyState === WebSocket.OPEN) { if (ws && ws.readyState === WebSocket.OPEN) {
// 顯示提交中狀態
const submitBtn = document.querySelector('.submit-btn');
const originalText = submitBtn.textContent;
submitBtn.textContent = '提交中...';
submitBtn.disabled = true;
ws.send(JSON.stringify({ ws.send(JSON.stringify({
type: 'submit_feedback', type: 'submit_feedback',
feedback: feedback, feedback: feedback,
images: images images: images
})); }));
alert('回饋已提交!感謝您的回饋。'); // 簡短延遲後自動關閉,不顯示 alert
window.close(); setTimeout(() => {
window.close();
}, 500);
} else { } else {
alert('WebSocket 連接異常,請重新整理頁面'); showNotification('WebSocket 連接異常,請重新整理頁面', 'error');
} }
} }
// 添加通知函數,替代 alert
function showNotification(message, type = 'info') {
// 創建通知元素
const notification = document.createElement('div');
notification.className = `notification ${type}`;
notification.textContent = message;
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: ${type === 'error' ? '#dc3545' : type === 'warning' ? '#ffc107' : '#007acc'};
color: white;
padding: 12px 20px;
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
z-index: 10000;
font-weight: bold;
max-width: 300px;
word-wrap: break-word;
`;
document.body.appendChild(notification);
// 3 秒後自動移除
setTimeout(() => {
if (notification.parentNode) {
notification.parentNode.removeChild(notification);
}
}, 3000);
}
function cancelFeedback() { function cancelFeedback() {
if (confirm('確定要取消回饋嗎?')) { if (confirm('確定要取消回饋嗎?')) {
window.close(); window.close();