feat: 图片保存到服务器,历史记录可显示图片
This commit is contained in:
@@ -228,6 +228,28 @@
|
||||
<img id="lightboxImage" src="" alt="放大图片">
|
||||
</div>
|
||||
|
||||
<!-- 隐藏的图片上传API处理 -->
|
||||
<script>
|
||||
// 图片上传到服务器(保存文件)
|
||||
async function uploadImageToServer(base64Data, fileName) {
|
||||
try {
|
||||
const response = await fetch('/api/v2/upload-image', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ image: base64Data, name: fileName })
|
||||
});
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
return result.path; // 返回服务器文件路径
|
||||
}
|
||||
return null;
|
||||
} catch (e) {
|
||||
console.error('图片上传失败:', e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Markdown渲染库 -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
<script>
|
||||
@@ -415,15 +437,22 @@
|
||||
console.log('Processing extraData for user message:', extraData);
|
||||
const bodyDiv = div.querySelector('.message-body');
|
||||
|
||||
// 处理图片
|
||||
// 处理图片(如果有服务器URL,显示图片)
|
||||
if (extraData.images && extraData.images.length > 0) {
|
||||
let imagesHtml = '<div class="history-images" style="margin-top:8px;display:flex;gap:8px;flex-wrap:wrap;">';
|
||||
for (const img of extraData.images) {
|
||||
// 历史记录只有图片元信息,显示占位符
|
||||
imagesHtml += `<div class="history-image-placeholder" style="padding:8px 12px;background:#f0f0f0;border-radius:8px;display:flex;align-items:center;gap:6px;font-size:13px;color:#666;">
|
||||
<i class="ri-image-line" style="color:#10a37f;"></i>
|
||||
<span>${escapeHtml(img.name || '图片')}</span>
|
||||
</div>`;
|
||||
if (img.url) {
|
||||
// 有服务器URL,显示真实图片
|
||||
imagesHtml += `<div class="history-image" style="display:inline-block;">
|
||||
<img src="${img.url}" style="max-width:300px;max-height:200px;border-radius:8px;cursor:zoom-in;" onclick="openImageLightbox('${img.url}')">
|
||||
</div>`;
|
||||
} else {
|
||||
// 没有URL,显示占位符
|
||||
imagesHtml += `<div class="history-image-placeholder" style="padding:8px 12px;background:#f0f0f0;border-radius:8px;display:flex;align-items:center;gap:6px;font-size:13px;color:#666;">
|
||||
<i class="ri-image-line" style="color:#10a37f;"></i>
|
||||
<span>${escapeHtml(img.name || '图片')}</span>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
imagesHtml += '</div>';
|
||||
if (bodyDiv) bodyDiv.insertAdjacentHTML('beforeend', imagesHtml);
|
||||
@@ -893,13 +922,15 @@
|
||||
lastSentFiles = files.map(f => ({
|
||||
name: f.name,
|
||||
type: f.type,
|
||||
content: f.content
|
||||
content: f.content,
|
||||
serverPath: f.serverPath // 服务器路径(用于历史记录)
|
||||
}));
|
||||
|
||||
for (const f of files) {
|
||||
if (f.type.startsWith('image/')) {
|
||||
// 图片直接显示
|
||||
html += `<div class="uploaded-image" style="margin-bottom:8px"><img src="${f.content}" style="max-width:300px;border-radius:8px" onclick="openImageLightbox('${f.content}')"></div>`;
|
||||
// 图片直接显示(用服务器路径或base64)
|
||||
const imgSrc = f.serverPath || f.content;
|
||||
html += `<div class="uploaded-image" style="margin-bottom:8px"><img src="${f.content}" style="max-width:300px;border-radius:8px" onclick="openImageLightbox('${imgSrc}')"></div>`;
|
||||
} else {
|
||||
// 文本文件显示名称和内容摘要
|
||||
html += `<div class="uploaded-file" style="padding:8px;background:#f5f5f5;border-radius:6px;margin-bottom:8px">`;
|
||||
@@ -924,7 +955,7 @@
|
||||
}
|
||||
|
||||
// 文件上传处理
|
||||
function handleFileUpload(event) {
|
||||
async function handleFileUpload(event) {
|
||||
const files = event.target.files;
|
||||
const previewArea = document.getElementById('filePreviewArea');
|
||||
|
||||
@@ -933,13 +964,23 @@
|
||||
|
||||
// 读取文件内容
|
||||
const reader = new FileReader();
|
||||
reader.onload = (e) => {
|
||||
reader.onload = async (e) => {
|
||||
const base64Content = e.target.result;
|
||||
|
||||
// 图片:先上传到服务器保存
|
||||
let serverPath = null;
|
||||
if (file.type.startsWith('image/')) {
|
||||
serverPath = await uploadImageToServer(base64Content, file.name);
|
||||
console.log('图片上传结果:', serverPath);
|
||||
}
|
||||
|
||||
const fileData = {
|
||||
id: fileId,
|
||||
name: file.name,
|
||||
type: file.type,
|
||||
size: file.size,
|
||||
content: e.target.result
|
||||
content: base64Content, // base64数据(用于多模态模型)
|
||||
serverPath: serverPath // 服务器路径(用于历史记录显示)
|
||||
};
|
||||
pendingFiles.push(fileData);
|
||||
|
||||
@@ -950,8 +991,9 @@
|
||||
|
||||
if (file.type.startsWith('image/')) {
|
||||
previewItem.classList.add('image-preview');
|
||||
// 预览用本地base64,显示更快
|
||||
previewItem.innerHTML = `
|
||||
<img src="${e.target.result}" alt="${file.name}">
|
||||
<img src="${base64Content}" alt="${file.name}" style="cursor:pointer" onclick="openImageLightbox('${serverPath || base64Content}')">
|
||||
<button class="file-remove" onclick="removeFile('${fileId}')"><i class="ri-close-line"></i></button>
|
||||
`;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user