小程序修正
This commit is contained in:
@@ -112,26 +112,19 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, nextTick, onMounted } from 'vue'
|
||||
import WorkcaseCreator from '@/components/WorkcaseCreator/WorkcaseCreator.uvue'
|
||||
import { guestAPI, workcaseChatAPI } from '@/api'
|
||||
import type { TbWorkcaseDTO } from '@/types'
|
||||
|
||||
// 接口定义
|
||||
interface Message {
|
||||
type : 'user' | 'bot'
|
||||
content : string
|
||||
time : string
|
||||
actions ?: string[] | null
|
||||
}
|
||||
|
||||
interface WorkcaseData {
|
||||
title : string
|
||||
category : string
|
||||
priority : string
|
||||
description : string
|
||||
contact : string
|
||||
images : string[]
|
||||
// 前端消息展示类型
|
||||
interface ChatMessageItem {
|
||||
type: 'user' | 'bot'
|
||||
content: string
|
||||
time: string
|
||||
actions?: string[] | null
|
||||
}
|
||||
|
||||
// 响应式数据
|
||||
const messages = ref<Message[]>([])
|
||||
const messages = ref<ChatMessageItem[]>([])
|
||||
const inputText = ref<string>('')
|
||||
const isTyping = ref<boolean>(false)
|
||||
const scrollTop = ref<number>(0)
|
||||
@@ -144,12 +137,17 @@
|
||||
const userInfo = ref({
|
||||
wechatId: '',
|
||||
username: '',
|
||||
phone: ''
|
||||
phone: '',
|
||||
userId: ''
|
||||
})
|
||||
const isMockMode = ref(true) // 开发环境mock模式
|
||||
|
||||
// AI 对话相关
|
||||
const chatId = ref<string>('') // 当前会话ID
|
||||
const currentTaskId = ref<string>('') // 当前任务ID(用于停止)
|
||||
|
||||
// 初始化用户信息
|
||||
function initUserInfo() {
|
||||
async function initUserInfo() {
|
||||
// #ifdef MP-WEIXIN
|
||||
// 正式环境:从微信获取用户信息
|
||||
// wx.login({
|
||||
@@ -165,9 +163,10 @@
|
||||
userInfo.value = {
|
||||
wechatId: '17857100375',
|
||||
username: '测试用户',
|
||||
phone: '17857100375'
|
||||
phone: '17857100375',
|
||||
userId: ''
|
||||
}
|
||||
doIdentify()
|
||||
await doIdentify()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,9 +176,9 @@
|
||||
itemList: ['员工 (17857100375)', '访客 (17857100376)'],
|
||||
success: (res) => {
|
||||
if (res.tapIndex === 0) {
|
||||
userInfo.value = { wechatId: '17857100375', username: '员工用户', phone: '17857100375' }
|
||||
userInfo.value = { wechatId: '17857100375', username: '员工用户', phone: '17857100375', userId: '' }
|
||||
} else {
|
||||
userInfo.value = { wechatId: '17857100376', username: '访客用户', phone: '17857100376' }
|
||||
userInfo.value = { wechatId: '17857100376', username: '访客用户', phone: '17857100376', userId: '' }
|
||||
}
|
||||
doIdentify()
|
||||
}
|
||||
@@ -187,31 +186,29 @@
|
||||
}
|
||||
|
||||
// 调用identify接口
|
||||
function doIdentify() {
|
||||
async function doIdentify() {
|
||||
uni.showLoading({ title: '登录中...' })
|
||||
uni.request({
|
||||
url: 'http://localhost:8180/urban-lifeline/system/guest/identify',
|
||||
method: 'POST',
|
||||
header: { 'Content-Type': 'application/json' },
|
||||
data: { wechatId: userInfo.value.wechatId, phone: userInfo.value.phone },
|
||||
success: (res : any) => {
|
||||
uni.hideLoading()
|
||||
if (res.statusCode === 200 && res.data?.success) {
|
||||
const loginDomain = res.data.data
|
||||
uni.setStorageSync('token', loginDomain.token || '')
|
||||
uni.setStorageSync('userInfo', JSON.stringify(loginDomain.user))
|
||||
uni.setStorageSync('wechatId', userInfo.value.wechatId)
|
||||
console.log('identify成功:', loginDomain)
|
||||
uni.showToast({ title: '登录成功', icon: 'success' })
|
||||
} else {
|
||||
console.error('identify失败:', res.data?.message)
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.hideLoading()
|
||||
console.error('identify请求失败:', err)
|
||||
try {
|
||||
const res = await guestAPI.identify({
|
||||
wechatId: userInfo.value.wechatId,
|
||||
phone: userInfo.value.phone
|
||||
})
|
||||
uni.hideLoading()
|
||||
if (res.success && res.data) {
|
||||
const loginDomain = res.data
|
||||
uni.setStorageSync('token', loginDomain.token || '')
|
||||
uni.setStorageSync('userInfo', JSON.stringify(loginDomain.user))
|
||||
uni.setStorageSync('wechatId', userInfo.value.wechatId)
|
||||
userInfo.value.userId = loginDomain.user?.userId || ''
|
||||
console.log('identify成功:', loginDomain)
|
||||
uni.showToast({ title: '登录成功', icon: 'success' })
|
||||
} else {
|
||||
console.error('identify失败:', res.message)
|
||||
}
|
||||
})
|
||||
} catch (err) {
|
||||
uni.hideLoading()
|
||||
console.error('identify请求失败:', err)
|
||||
}
|
||||
}
|
||||
|
||||
// 生命周期
|
||||
@@ -259,7 +256,7 @@
|
||||
})
|
||||
|
||||
// 发送消息
|
||||
function sendMessage() {
|
||||
async function sendMessage() {
|
||||
const text = inputText.value.trim()
|
||||
if (!text || isTyping.value) return
|
||||
|
||||
@@ -267,8 +264,115 @@
|
||||
addMessage('user', text)
|
||||
inputText.value = ''
|
||||
|
||||
// 模拟AI回复
|
||||
simulateAIResponse(text)
|
||||
// 调用AI聊天接口
|
||||
await callAIChat(text)
|
||||
}
|
||||
|
||||
// 调用AI聊天接口
|
||||
async function callAIChat(query : string) {
|
||||
isTyping.value = true
|
||||
|
||||
try {
|
||||
// 如果没有会话ID,先创建会话
|
||||
if (!chatId.value) {
|
||||
const createRes = await workcaseChatAPI.createChat({
|
||||
title: '智能助手对话',
|
||||
userId: userInfo.value.userId || userInfo.value.wechatId
|
||||
})
|
||||
if (createRes.success && createRes.data) {
|
||||
chatId.value = createRes.data.chatId || ''
|
||||
console.log('创建会话成功:', chatId.value)
|
||||
} else {
|
||||
throw new Error(createRes.message || '创建会话失败')
|
||||
}
|
||||
}
|
||||
|
||||
// 准备流式对话
|
||||
const prepareRes = await workcaseChatAPI.prepareChatMessageSession({
|
||||
chatId: chatId.value,
|
||||
message: query
|
||||
})
|
||||
if (!prepareRes.success || !prepareRes.data) {
|
||||
throw new Error(prepareRes.message || '准备对话失败')
|
||||
}
|
||||
const sessionId = prepareRes.data
|
||||
console.log('准备流式对话成功:', sessionId)
|
||||
|
||||
// 添加空的AI消息占位
|
||||
const messageIndex = messages.value.length
|
||||
addMessage('bot', '')
|
||||
|
||||
// 建立SSE连接
|
||||
streamChat(sessionId, messageIndex)
|
||||
} catch (error : any) {
|
||||
console.error('AI聊天失败:', error)
|
||||
isTyping.value = false
|
||||
addMessage('bot', '抱歉,AI服务暂时不可用,请稍后重试。')
|
||||
}
|
||||
}
|
||||
|
||||
// SSE 流式对话
|
||||
function streamChat(sessionId : string, messageIndex : number) {
|
||||
const url = `http://localhost:8180${workcaseChatAPI.getStreamUrl(sessionId)}`
|
||||
console.log('建立SSE连接:', url)
|
||||
|
||||
const requestTask = uni.request({
|
||||
url: url,
|
||||
method: 'GET',
|
||||
header: { 'Accept': 'text/event-stream' },
|
||||
enableChunked: true,
|
||||
success: (res : any) => {
|
||||
console.log('SSE请求完成:', res)
|
||||
isTyping.value = false
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error('SSE请求失败:', err)
|
||||
isTyping.value = false
|
||||
messages.value[messageIndex].content = '抱歉,网络连接失败,请稍后重试。'
|
||||
}
|
||||
})
|
||||
|
||||
// 监听分块数据
|
||||
requestTask.onChunkReceived((res : any) => {
|
||||
try {
|
||||
const decoder = new TextDecoder('utf-8')
|
||||
const text = decoder.decode(new Uint8Array(res.data))
|
||||
console.log('收到分块数据:', text)
|
||||
|
||||
const lines = text.split('\n')
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('data:')) {
|
||||
const dataStr = line.substring(5).trim()
|
||||
if (dataStr && dataStr !== '[DONE]') {
|
||||
try {
|
||||
const data = JSON.parse(dataStr)
|
||||
const event = data.event
|
||||
|
||||
if (event === 'message' || event === 'agent_message') {
|
||||
if (data.answer) {
|
||||
messages.value[messageIndex].content += data.answer
|
||||
}
|
||||
} else if (event === 'message_end') {
|
||||
isTyping.value = false
|
||||
if (data.task_id) {
|
||||
currentTaskId.value = data.task_id
|
||||
}
|
||||
} else if (event === 'error') {
|
||||
console.error('SSE错误:', data.message)
|
||||
isTyping.value = false
|
||||
messages.value[messageIndex].content = data.message || '抱歉,发生错误,请稍后重试。'
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('解析SSE数据失败:', dataStr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('处理分块数据失败:', e)
|
||||
}
|
||||
nextTick(() => scrollToBottom())
|
||||
})
|
||||
}
|
||||
|
||||
// 添加消息
|
||||
@@ -359,7 +463,7 @@
|
||||
}
|
||||
|
||||
// 工单创建成功
|
||||
function onWorkcaseCreated(workcaseData : WorkcaseData) {
|
||||
function onWorkcaseCreated(workcaseData : TbWorkcaseDTO) {
|
||||
hideCreator()
|
||||
|
||||
uni.showToast({
|
||||
@@ -368,7 +472,7 @@
|
||||
})
|
||||
|
||||
// 添加成功消息
|
||||
addMessage('bot', `工单创建成功!\n标题:${workcaseData.title}\n分类:${workcaseData.category}\n我们会尽快处理您的问题。`, ['查看工单', '创建新工单'])
|
||||
addMessage('bot', `工单创建成功!\n类型:${workcaseData.type || ''}\n设备:${workcaseData.device || ''}\n我们会尽快处理您的问题。`, ['查看工单', '创建新工单'])
|
||||
}
|
||||
|
||||
// 跳转到工单列表
|
||||
@@ -408,9 +512,9 @@
|
||||
}
|
||||
|
||||
// 处理快速问题
|
||||
function handleQuickQuestion(question : string) {
|
||||
async function handleQuickQuestion(question : string) {
|
||||
addMessage('user', question)
|
||||
simulateAIResponse(question)
|
||||
await callAIChat(question)
|
||||
}
|
||||
|
||||
// 显示上传选项
|
||||
|
||||
Reference in New Issue
Block a user