mirror of
https://github.com/Minidoracat/mcp-feedback-enhanced.git
synced 2025-07-27 10:42:25 +08:00
✨ 增強回饋文本生成,新增圖片的 Base64 預覽信息及兼容性說明,並將 alert 替換為通知功能以改善用戶體驗。
This commit is contained in:
parent
b0766f08ed
commit
c02961d234
34
server.py
34
server.py
@ -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 "用戶未提供任何回饋內容。"
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user