refactor: split project into web and server directories
- Move frontend to web/ directory - Add server/ directory for backend - Restructure project for前后端分离架构 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
102
web/src/composables/useChat.js
Normal file
102
web/src/composables/useChat.js
Normal file
@@ -0,0 +1,102 @@
|
||||
import { nextTick, ref } from 'vue'
|
||||
|
||||
const initialMessages = [
|
||||
{
|
||||
id: 1,
|
||||
role: 'agent',
|
||||
text: '我已读取当前报销、发票、行程和制度命中情况。当前建议:优先处理即将超时与高风险单据。'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
role: 'user',
|
||||
text: '请列出今天最需要关注的风险。'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
role: 'agent',
|
||||
text: '主要风险包括:3 笔单据将在 30 分钟内超时,市场部存在 2 笔高风险差旅报销,另有 1 笔报销缺少酒店入住清单。'
|
||||
}
|
||||
]
|
||||
|
||||
export const prompts = ['生成审批意见', '列出补件清单', '解释风险原因', '生成运营简报']
|
||||
|
||||
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 (text.includes('超时') || text.includes('SLA')) {
|
||||
return '当前最紧急的是 3 笔即将超时单据,建议先按剩余处理时长排序,并把缺附件单据转给申请人补齐。'
|
||||
}
|
||||
if (text.includes('高风险') || text.includes('风险')) {
|
||||
return '高风险主要集中在市场部差旅报销,风险点包括住宿超标、重复发票疑似命中、行程说明缺失。建议人工复核后再通过。'
|
||||
}
|
||||
if (text.includes('部门')) {
|
||||
return '从待处理金额看,销售部与研发中心占比最高;从异常占比看,市场部更需要优先关注。'
|
||||
}
|
||||
if (text.includes('简报')) {
|
||||
return '运营简报:今日待审批 12 单,高风险 4 单,平均审批 5.6h,SLA 达成率 96%。建议优先处理差旅报销和即将超时单据。'
|
||||
}
|
||||
if (text.includes('补件') || text.includes('附件')) {
|
||||
return '建议补件清单:酒店入住水单、完整行程单、发票原件或验真结果、直属经理确认记录。'
|
||||
}
|
||||
if (text.includes('审批意见')) {
|
||||
return c
|
||||
? `${c.id} 建议审批意见:费用归属与预算中心基本匹配,请补充必要说明后通过。`
|
||||
: '建议审批意见:当前单据存在待确认项,请先完成风险核查和附件补齐后再审批。'
|
||||
}
|
||||
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 }))
|
||||
}
|
||||
|
||||
function openNewChat() {
|
||||
activeCase.value = null
|
||||
activeView.value = 'chat'
|
||||
}
|
||||
|
||||
return {
|
||||
messages, draft, uploadedFiles, messageList, activeCase, prompts,
|
||||
sendMessage, handleUpload, openChat, openNewChat, scrollToBottom
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user