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
2026-04-28 17:20:52 +08:00
|
|
|
|
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
|
2026-04-29 23:35:56 +08:00
|
|
|
|
if (text.includes('出差申请') || text.includes('出差'))
|
|
|
|
|
|
return '好的,我来帮您处理出差申请。请提供以下信息:\n1. 出发城市和目的地\n2. 出差日期和天数\n3. 出差事由\n4. 预计费用预算'
|
|
|
|
|
|
if (text.includes('机票') || text.includes('飞机'))
|
|
|
|
|
|
return '我来帮您查询机票信息。请告诉我:\n1. 出发城市 → 目的城市\n2. 出发日期\n3. 偏好的时间段(上午/下午/晚间)\n4. 舱位要求(经济舱/商务舱)'
|
|
|
|
|
|
if (text.includes('酒店') || text.includes('住宿'))
|
|
|
|
|
|
return '好的,帮您查找合适的酒店。请提供:\n1. 入住城市和区域偏好\n2. 入住和退房日期\n3. 星级/价位要求\n4. 是否需要含早餐'
|
|
|
|
|
|
if (text.includes('火车票') || text.includes('高铁'))
|
|
|
|
|
|
return '帮您查询火车票。请告诉我:\n1. 出发站 → 到达站\n2. 出行日期\n3. 座位偏好(二等座/一等座/商务座)\n4. 偏好的出发时间段'
|
|
|
|
|
|
if (text.includes('审批意见'))
|
|
|
|
|
|
return c ? `${c.id} 建议审批意见:费用归属与预算中心匹配,建议保留业务说明后通过。` : '请先选择一份单据再生成审批意见。'
|
|
|
|
|
|
if (text.includes('补件'))
|
|
|
|
|
|
return '补件优先级:业务目的说明、行程或客户名单、直属经理确认记录。'
|
|
|
|
|
|
if (text.includes('差旅政策') || text.includes('政策'))
|
|
|
|
|
|
return '当前差旅政策要点:\n• 住宿标准:一线城市 600 元/晚,二线城市 400 元/晚\n• 机票:优先经济舱,3 小时以上可申请商务舱\n• 高铁:优先二等座,4 小时以上可申请一等座\n• 每日餐饮补贴:120 元'
|
|
|
|
|
|
return '好的,我已记录您的需求。请问还需要什么帮助?我还可以帮您查询差旅政策、预订机票酒店火车票等。'
|
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
2026-04-28 17:20:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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 }))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-04-29 23:35:56 +08:00
|
|
|
|
function openNewChat() {
|
|
|
|
|
|
activeCase.value = null
|
|
|
|
|
|
activeView.value = 'chat'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
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
2026-04-28 17:20:52 +08:00
|
|
|
|
return {
|
|
|
|
|
|
messages, draft, uploadedFiles, messageList, activeCase, prompts,
|
2026-04-29 23:35:56 +08:00
|
|
|
|
sendMessage, handleUpload, openChat, openNewChat, scrollToBottom
|
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
2026-04-28 17:20:52 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|