текст из pdf распознается, все работает, добавлены все функции из файла работы с базой данных db_cli.py. Готовность к оптимизации интерфейса.
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
@app.get("/favicon.ico")
|
||||
async def favicon():
|
||||
file_path = os.path.join("static", "favicon.ico")
|
||||
if os.path.exists(file_path):
|
||||
return FileResponse(file_path)
|
||||
raise HTTPException(status_code=404)
|
||||
+20
-2
@@ -178,16 +178,34 @@
|
||||
<i class="fa-solid fa-robot mr-1"></i> ИИ-Ассистент
|
||||
</p>
|
||||
<p class="text-slate-800 text-xs sm:text-sm leading-relaxed">
|
||||
Привет! У каждого пользователя свое изолированное пространство задач. Вы можете задавать вопросы нейросети или ставить персональные задачи.
|
||||
Привет! У каждого пользователя свое изолированное пространство задач. Вы можете задавать вопросы нейросети, прикреплять файлы или ставить персональные задачи.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Превью прикрепленного файла -->
|
||||
<div id="file-preview-container" class="hidden px-4 py-2 bg-slate-100 border-t border-slate-200 flex items-center justify-between text-xs text-slate-700">
|
||||
<div class="flex items-center gap-2 truncate">
|
||||
<i class="fa-solid fa-paperclip text-indigo-600"></i>
|
||||
<span id="file-name-display" class="font-medium truncate">file.pdf</span>
|
||||
<span id="file-size-display" class="text-slate-400 text-[10px]">(0 KB)</span>
|
||||
</div>
|
||||
<button type="button" onclick="clearAttachedFile()" class="text-slate-400 hover:text-red-500 p-1 transition">
|
||||
<i class="fa-solid fa-xmark text-sm"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="p-2.5 pb-6 bg-white border-t border-slate-200 shrink-0 z-10 shadow-lg">
|
||||
<div class="flex items-center gap-2">
|
||||
<!-- Скрытый инпут и кнопка прикрепления файла -->
|
||||
<input type="file" id="file-input" class="hidden" onchange="handleFileSelect(event)" accept=".png,.jpg,.jpeg,.pdf,.txt,.csv,.xlsx">
|
||||
<button type="button" onclick="document.getElementById('file-input').click()" class="text-slate-500 hover:text-indigo-600 p-2 rounded-xl transition" title="Прикрепить файл">
|
||||
<i class="fa-solid fa-paperclip text-lg"></i>
|
||||
</button>
|
||||
|
||||
<div class="flex-1 bg-slate-100 border border-slate-300 rounded-2xl px-3 py-1.5 focus-within:border-indigo-600 focus-within:bg-white transition">
|
||||
<textarea id="user-input" rows="1" autocomplete="off" autocorrect="off" spellcheck="false"
|
||||
placeholder="Команда или вопрос..."
|
||||
placeholder="Команда, вопрос или описание файла..."
|
||||
class="w-full bg-transparent text-slate-900 text-sm focus:outline-none resize-none overflow-y-auto max-h-[80px] leading-normal no-scrollbar"></textarea>
|
||||
</div>
|
||||
<button type="button" id="send-btn" onclick="sendMessage()" class="bg-indigo-600 active:bg-indigo-800 text-white font-semibold px-3.5 py-2.5 rounded-2xl text-xs sm:text-sm transition flex items-center justify-center gap-1.5 shrink-0 shadow-sm">
|
||||
|
||||
+53
-5
@@ -1,3 +1,33 @@
|
||||
let selectedFile = null;
|
||||
|
||||
function handleFileSelect(e) {
|
||||
const file = e.target.files[0];
|
||||
if (!file) return;
|
||||
|
||||
if (file.size > 15 * 1024 * 1024) {
|
||||
alert("Файл слишком большой. Максимальный размер: 15 МБ");
|
||||
e.target.value = "";
|
||||
return;
|
||||
}
|
||||
|
||||
selectedFile = file;
|
||||
const fileNameEl = document.getElementById("file-name-display");
|
||||
const fileSizeEl = document.getElementById("file-size-display");
|
||||
const previewContainer = document.getElementById("file-preview-container");
|
||||
|
||||
if (fileNameEl) fileNameEl.innerText = file.name;
|
||||
if (fileSizeEl) fileSizeEl.innerText = `(${(file.size / 1024).toFixed(1)} KB)`;
|
||||
if (previewContainer) previewContainer.classList.remove("hidden");
|
||||
}
|
||||
|
||||
function clearAttachedFile() {
|
||||
selectedFile = null;
|
||||
const fileInput = document.getElementById("file-input");
|
||||
const previewContainer = document.getElementById("file-preview-container");
|
||||
if (fileInput) fileInput.value = "";
|
||||
if (previewContainer) previewContainer.classList.add("hidden");
|
||||
}
|
||||
|
||||
async function sendMessage(e) {
|
||||
if (e && e.preventDefault) e.preventDefault();
|
||||
|
||||
@@ -8,13 +38,19 @@ async function sendMessage(e) {
|
||||
if (!input || !chatWindow) return;
|
||||
const text = input.value.trim();
|
||||
|
||||
if (!text) return;
|
||||
if (!text && !selectedFile) return;
|
||||
|
||||
let userDisplayHtml = escapeHtml(text);
|
||||
if (selectedFile) {
|
||||
userDisplayHtml = `<div class="font-bold border-b border-indigo-400/40 pb-1 mb-1 text-[11px] flex items-center gap-1.5">
|
||||
<i class="fa-solid fa-file"></i> ${escapeHtml(selectedFile.name)}
|
||||
</div>` + userDisplayHtml;
|
||||
}
|
||||
|
||||
// Вывод сообщения пользователя
|
||||
const userMsgHtml = `
|
||||
<div class="flex justify-end mb-3">
|
||||
<div class="bg-indigo-600 text-white rounded-2xl px-4 py-2.5 max-w-2xl text-xs sm:text-sm shadow-sm">
|
||||
${escapeHtml(text)}
|
||||
${userDisplayHtml}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@@ -33,7 +69,17 @@ async function sendMessage(e) {
|
||||
const isGuest = typeof IS_GUEST !== 'undefined' ? IS_GUEST : (localStorage.getItem("scud_is_guest") === "true");
|
||||
|
||||
const endpoint = isGuest ? "/api/v1/chat/guest" : "/api/v1/chat";
|
||||
const headers = { "Content-Type": "application/json" };
|
||||
|
||||
// Формируем единый FormData без дублирования
|
||||
const formData = new FormData();
|
||||
formData.append("session_id", "web_session_main");
|
||||
formData.append("message", text || "Проанализируй прикрепленный файл");
|
||||
|
||||
if (selectedFile instanceof File) {
|
||||
formData.append("file", selectedFile, selectedFile.name);
|
||||
}
|
||||
|
||||
const headers = {};
|
||||
if (!isGuest && token) {
|
||||
headers["Authorization"] = "Bearer " + token;
|
||||
}
|
||||
@@ -42,7 +88,7 @@ async function sendMessage(e) {
|
||||
const res = await fetch(endpoint, {
|
||||
method: "POST",
|
||||
headers: headers,
|
||||
body: JSON.stringify({ session_id: "web_session_main", message: text })
|
||||
body: formData
|
||||
});
|
||||
|
||||
if (res.status === 401 && !isGuest) {
|
||||
@@ -65,6 +111,8 @@ async function sendMessage(e) {
|
||||
chatWindow.insertAdjacentHTML("beforeend", botMsgHtml);
|
||||
chatWindow.scrollTop = chatWindow.scrollHeight;
|
||||
|
||||
clearAttachedFile();
|
||||
|
||||
if (!isGuest && typeof loadTasks === 'function') {
|
||||
loadTasks();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user