feat(ai-house): 重构找房聊天交互
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
const assert = require('node:assert/strict')
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
|
||||
const pagePath = path.resolve(__dirname, '../pages/ai-house/index.vue')
|
||||
const source = fs.readFileSync(pagePath, 'utf8')
|
||||
const scriptMatch = source.match(/<script>([\s\S]*?)<\/script>/)
|
||||
|
||||
assert.ok(scriptMatch, '未找到 AI 找房页面脚本')
|
||||
|
||||
const componentScript = scriptMatch[1]
|
||||
.replace(/^\s*import .*$/gm, '')
|
||||
.replace('export default {', 'return {')
|
||||
const component = new Function(
|
||||
'HouseAiConfigApi',
|
||||
'HouseAiChatApi',
|
||||
'storage',
|
||||
'USER_ID',
|
||||
'apiUrl',
|
||||
componentScript
|
||||
)({}, {}, {}, 'userId', 'http://localhost')
|
||||
|
||||
function createPageVm() {
|
||||
const vm = component.data()
|
||||
Object.entries(component.methods).forEach(([name, method]) => {
|
||||
vm[name] = method.bind(vm)
|
||||
})
|
||||
vm.scrollToBottom = () => {}
|
||||
return vm
|
||||
}
|
||||
|
||||
function receiveLocationResponse(fieldName, locationCards) {
|
||||
const vm = createPageVm()
|
||||
const response = {
|
||||
type: 'house_ai_result',
|
||||
answer: '已按已维护的地点资料筛选,以下地点可供参考。'
|
||||
}
|
||||
response[fieldName] = locationCards
|
||||
vm.handleSocketMessage(JSON.stringify(response))
|
||||
return vm.messages.find((message) => message.type === 'location')
|
||||
}
|
||||
|
||||
const locationCard = {
|
||||
location_id: 101,
|
||||
city: '南宁市',
|
||||
location_name: '五象航洋城',
|
||||
parent_location_name: '五象新区',
|
||||
tags: ['停车方便'],
|
||||
knowledge_items: [{
|
||||
topic: 'parking',
|
||||
title: '停车',
|
||||
parking_available: true,
|
||||
parking_fee: '月租 300 元'
|
||||
}]
|
||||
}
|
||||
|
||||
const locationMessage = receiveLocationResponse('location_cards', JSON.stringify([locationCard]))
|
||||
|
||||
assert.ok(locationMessage, '地点咨询回包应创建地点卡片消息')
|
||||
assert.ok(Array.isArray(locationMessage.locationCards), '地点卡片应转换为数组')
|
||||
assert.equal(locationMessage.locationCards[0].locationId, 101)
|
||||
assert.equal(locationMessage.locationCards[0].locationName, '五象航洋城')
|
||||
assert.equal(locationMessage.locationCards[0].knowledgeItems[0].parkingAvailable, true)
|
||||
|
||||
const backendLocationMessage = receiveLocationResponse('locationCards', [{
|
||||
locationId: 102,
|
||||
city: '南宁市',
|
||||
locationName: '会展航洋城',
|
||||
knowledgeItems: []
|
||||
}])
|
||||
|
||||
assert.ok(backendLocationMessage, '后端驼峰地点卡片回包应保持兼容')
|
||||
assert.equal(backendLocationMessage.locationCards[0].locationName, '会展航洋城')
|
||||
|
||||
console.log('地点咨询回包能够创建可渲染的地点卡片消息')
|
||||
@@ -0,0 +1,98 @@
|
||||
const assert = require('node:assert/strict')
|
||||
const fs = require('node:fs')
|
||||
const path = require('node:path')
|
||||
|
||||
const pagePath = path.resolve(__dirname, '../pages/ai-house/index.vue')
|
||||
const source = fs.readFileSync(pagePath, 'utf8')
|
||||
const scriptMatch = source.match(/<script>([\s\S]*?)<\/script>/)
|
||||
|
||||
assert.ok(scriptMatch, 'AI house page script is missing')
|
||||
|
||||
const savedValues = new Map()
|
||||
const storage = {
|
||||
get(key) {
|
||||
return savedValues.get(key) || false
|
||||
},
|
||||
set(key, value) {
|
||||
savedValues.set(key, value)
|
||||
}
|
||||
}
|
||||
const clearCalls = []
|
||||
const componentScript = scriptMatch[1]
|
||||
.replace(/^\s*import .*$/gm, '')
|
||||
.replace('export default {', 'return {')
|
||||
const component = new Function(
|
||||
'HouseAiConfigApi',
|
||||
'HouseAiChatApi',
|
||||
'storage',
|
||||
'USER_ID',
|
||||
'apiUrl',
|
||||
componentScript
|
||||
)(
|
||||
{},
|
||||
{
|
||||
clearHouseAiSession(payload) {
|
||||
clearCalls.push(payload)
|
||||
return Promise.resolve()
|
||||
}
|
||||
},
|
||||
storage,
|
||||
'userId',
|
||||
'http://localhost'
|
||||
)
|
||||
|
||||
global.uni = {
|
||||
showToast() {}
|
||||
}
|
||||
|
||||
function createPageVm() {
|
||||
const vm = component.data()
|
||||
Object.entries(component.methods).forEach(([name, method]) => {
|
||||
vm[name] = method.bind(vm)
|
||||
})
|
||||
vm.scrollToBottom = () => {}
|
||||
return vm
|
||||
}
|
||||
|
||||
const firstPage = createPageVm()
|
||||
firstPage.loginUserId = 1001
|
||||
firstPage.conversationId = 'house-ai-1001-existing'
|
||||
firstPage.messages = [firstPage.createMessage('user', 'text', { content: 'Need a two-bedroom home' })]
|
||||
firstPage.messageSubmitted = true
|
||||
firstPage.form = {
|
||||
building: '阳光小区',
|
||||
area: '90',
|
||||
budget: '3000'
|
||||
}
|
||||
const finderQuestion = firstPage.buildFormQuestion()
|
||||
assert.ok(finderQuestion.includes('阳光小区'))
|
||||
assert.ok(finderQuestion.includes('90'))
|
||||
assert.ok(finderQuestion.includes('3000'))
|
||||
firstPage.persistSession()
|
||||
|
||||
const restoredPage = createPageVm()
|
||||
restoredPage.loginUserId = 1001
|
||||
assert.equal(restoredPage.restoreSession(), true)
|
||||
assert.equal(restoredPage.conversationId, 'house-ai-1001-existing')
|
||||
assert.equal(restoredPage.messages[0].content, 'Need a two-bedroom home')
|
||||
assert.equal(restoredPage.messageSubmitted, true)
|
||||
assert.equal(restoredPage.createMessage('ai', 'text').id, 'msg-1')
|
||||
|
||||
restoredPage.aiConfig.welcomeMessage = 'Welcome back'
|
||||
restoredPage.clearSession().then(() => {
|
||||
assert.deepEqual(clearCalls, [{ conversationId: 'house-ai-1001-existing' }])
|
||||
assert.notEqual(restoredPage.conversationId, 'house-ai-1001-existing')
|
||||
assert.equal(restoredPage.messages.length, 1)
|
||||
assert.equal(restoredPage.messages[0].type, 'form')
|
||||
assert.equal(restoredPage.messages[0].content, 'Welcome back')
|
||||
assert.equal(restoredPage.messageSubmitted, false)
|
||||
|
||||
const storedSession = storage.get('house-ai-session-1001')
|
||||
assert.equal(storedSession.conversationId, restoredPage.conversationId)
|
||||
assert.equal(storedSession.messages.length, 1)
|
||||
|
||||
console.log('AI house session persistence and clearing checks passed')
|
||||
}).catch((error) => {
|
||||
console.error(error)
|
||||
process.exitCode = 1
|
||||
})
|
||||
Reference in New Issue
Block a user