feat: refactor monolithic App.vue into modular Vue component architecture
- Extract 711-line App.vue into 15+ focused files across 5 directories - Add data layer (icons, metrics, policies, auditTrail, requests) - Add composables (useNavigation, useRequests, useChat, useToast) - Add layout components (SidebarRail, TopBar, FilterBar) - Add shared components (PanelHead, InfoRow, ToastNotification) - Add business component (RequestTable) and 5 view components - Extract global CSS to assets/styles/global.css - Add start.sh with WSL/Windows cross-platform support - Add .gitignore for node_modules, dist, and IDE dirs
This commit is contained in:
63
src/composables/useChat.js
Normal file
63
src/composables/useChat.js
Normal file
@@ -0,0 +1,63 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user