|
@@ -1,5 +1,5 @@
|
|
|
import { ref } from 'vue'
|
|
import { ref } from 'vue'
|
|
|
-import type { ChatMessage, ToolCallInfo, SessionListItem } from './interface'
|
|
|
|
|
|
|
+import type { ChatMessage, ToolCallInfo, SessionListItem, UploadedFile } from './interface'
|
|
|
import { useUserStore } from '@/stores/user'
|
|
import { useUserStore } from '@/stores/user'
|
|
|
import { chatDB } from './chatDB'
|
|
import { chatDB } from './chatDB'
|
|
|
import {
|
|
import {
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
deleteAiSession,
|
|
deleteAiSession,
|
|
|
cancelAiChat,
|
|
cancelAiChat,
|
|
|
resolveAiPermission,
|
|
resolveAiPermission,
|
|
|
|
|
+ uploadAiFile,
|
|
|
} from '@/service/aiChat'
|
|
} from '@/service/aiChat'
|
|
|
|
|
|
|
|
export function useAiChat() {
|
|
export function useAiChat() {
|
|
@@ -18,6 +19,8 @@ export function useAiChat() {
|
|
|
const currentSessionId = ref('')
|
|
const currentSessionId = ref('')
|
|
|
const welcomeMessage = ref('')
|
|
const welcomeMessage = ref('')
|
|
|
const sessionList = ref<SessionListItem[]>([])
|
|
const sessionList = ref<SessionListItem[]>([])
|
|
|
|
|
+ const pendingFiles = ref<UploadedFile[]>([])
|
|
|
|
|
+ const isUploading = ref(false)
|
|
|
const isLoadingSession = ref(false)
|
|
const isLoadingSession = ref(false)
|
|
|
|
|
|
|
|
const userStore = useUserStore()
|
|
const userStore = useUserStore()
|
|
@@ -209,6 +212,44 @@ export function useAiChat() {
|
|
|
|
|
|
|
|
// ============ 消息发送 ============
|
|
// ============ 消息发送 ============
|
|
|
|
|
|
|
|
|
|
+ // ============ 文件上传 ============
|
|
|
|
|
+
|
|
|
|
|
+ async function handleUploadFile(file: File) {
|
|
|
|
|
+ // 限制数量
|
|
|
|
|
+ if (pendingFiles.value.length >= 5) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ // 限制大小
|
|
|
|
|
+ if (file.size > 2 * 1024 * 1024) {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ isUploading.value = true
|
|
|
|
|
+ try {
|
|
|
|
|
+ const result = await uploadAiFile(file)
|
|
|
|
|
+ if (result) {
|
|
|
|
|
+ pendingFiles.value.push({
|
|
|
|
|
+ key: result.key,
|
|
|
|
|
+ fileName: result.fileName,
|
|
|
|
|
+ path: result.path,
|
|
|
|
|
+ size: result.size,
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ catch {
|
|
|
|
|
+ // 忽略
|
|
|
|
|
+ }
|
|
|
|
|
+ finally {
|
|
|
|
|
+ isUploading.value = false
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function removePendingFile(index: number) {
|
|
|
|
|
+ pendingFiles.value.splice(index, 1)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // ============ 消息发送 ============
|
|
|
|
|
+
|
|
|
function generateId(): string {
|
|
function generateId(): string {
|
|
|
return `${Date.now()}-${Math.random().toString(36).slice(2)}`
|
|
return `${Date.now()}-${Math.random().toString(36).slice(2)}`
|
|
|
}
|
|
}
|
|
@@ -216,7 +257,16 @@ export function useAiChat() {
|
|
|
async function sendMessage(content: string) {
|
|
async function sendMessage(content: string) {
|
|
|
if (!content.trim() || isStreaming.value) return
|
|
if (!content.trim() || isStreaming.value) return
|
|
|
|
|
|
|
|
- // 添加用户消息
|
|
|
|
|
|
|
+ // 构建实际发送的消息(包含文件上下文)
|
|
|
|
|
+ let actualMessage = content.trim()
|
|
|
|
|
+ if (pendingFiles.value.length > 0) {
|
|
|
|
|
+ const filePaths = pendingFiles.value.map(f => f.path).join(', ')
|
|
|
|
|
+ actualMessage = `[用户上传了文件: ${filePaths},请使用 readTextFile 工具读取文件内容后进行分析]\n\n${actualMessage}`
|
|
|
|
|
+ // 清空待发送文件
|
|
|
|
|
+ pendingFiles.value = []
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 添加用户消息(显示原始内容,不含注入的文件提示)
|
|
|
messages.value.push({
|
|
messages.value.push({
|
|
|
id: generateId(),
|
|
id: generateId(),
|
|
|
role: 'user',
|
|
role: 'user',
|
|
@@ -244,7 +294,7 @@ export function useAiChat() {
|
|
|
Authorization: `Bearer ${userStore.token}`,
|
|
Authorization: `Bearer ${userStore.token}`,
|
|
|
},
|
|
},
|
|
|
body: JSON.stringify({
|
|
body: JSON.stringify({
|
|
|
- message: content.trim(),
|
|
|
|
|
|
|
+ message: actualMessage,
|
|
|
sessionId: currentSessionId.value,
|
|
sessionId: currentSessionId.value,
|
|
|
}),
|
|
}),
|
|
|
})
|
|
})
|
|
@@ -433,6 +483,8 @@ export function useAiChat() {
|
|
|
welcomeMessage,
|
|
welcomeMessage,
|
|
|
sessionList,
|
|
sessionList,
|
|
|
isLoadingSession,
|
|
isLoadingSession,
|
|
|
|
|
+ pendingFiles,
|
|
|
|
|
+ isUploading,
|
|
|
sendMessage,
|
|
sendMessage,
|
|
|
cancelChat,
|
|
cancelChat,
|
|
|
clearMessages,
|
|
clearMessages,
|
|
@@ -442,5 +494,7 @@ export function useAiChat() {
|
|
|
createNewSession,
|
|
createNewSession,
|
|
|
loadSession,
|
|
loadSession,
|
|
|
deleteSession,
|
|
deleteSession,
|
|
|
|
|
+ handleUploadFile,
|
|
|
|
|
+ removePendingFile,
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|