Files
X-Financial/src/composables/useChat.js

64 lines
2.5 KiB
JavaScript
Raw Normal View History

import { nextTick, ref } from 'vue'
import { initialMessages, prompts } from '../data/requests.js'
export function useChat(activeView) {
const messages = ref([...initialMessages])
const draft = ref('')
const uploadedFiles = ref([])
const messageList = ref(null)
const activeCase = ref(null)
function agentReply(text) {
const c = activeCase.value
if (!c) return '建议先核对政策阈值和附件完整性,再决定通过、退回补件或转人工复核。'
if (text.includes('审批')) return `${c.id} 建议审批意见:发票验真通过,费用归属与预算中心匹配;${c.risk} 已触发规则提示,建议保留业务说明后通过。`
if (text.includes('补件')) return '补件优先级:业务目的说明、行程或客户名单、直属经理确认记录。'
if (text.includes('拦截')) return `拦截原因是 ${c.risk},该风险需要财务复核并留下制度依据。`
if (text.includes('审计')) return `审计摘要:${c.person} 提交 ${c.amount} 报销,命中 ${c.risk},系统已保留 AI 判断。`
return '建议先核对政策阈值和附件完整性,再决定通过、退回补件或转人工复核。'
}
function scrollToBottom() {
nextTick(() => messageList.value?.scrollTo({ top: messageList.value.scrollHeight, behavior: 'smooth' }))
}
function sendMessage() {
const text = draft.value.trim()
if (!text) return false
messages.value.push({ id: Date.now(), role: 'user', text })
draft.value = ''
setTimeout(() => {
messages.value.push({ id: Date.now() + 1, role: 'agent', text: agentReply(text) })
scrollToBottom()
}, 260)
return true
}
function handleUpload(event) {
uploadedFiles.value = Array.from(event.target.files ?? []).map((file) => ({
name: file.name,
size: file.size
}))
if (uploadedFiles.value.length) {
const names = uploadedFiles.value.map((file) => file.name).join('、')
messages.value.push({
id: Date.now(),
role: 'agent',
text: `已接收 ${uploadedFiles.value.length} 个附件:${names}。我会优先核对发票验真、费用标准、预算归属和必备审批材料。`
})
scrollToBottom()
}
}
function openChat(request) {
activeCase.value = request
activeView.value = 'chat'
nextTick(() => messageList.value?.scrollTo({ top: messageList.value.scrollHeight }))
}
return {
messages, draft, uploadedFiles, messageList, activeCase, prompts,
sendMessage, handleUpload, openChat, scrollToBottom
}
}